我正在开发一个相当简单的DSL,并希望更自然地声明和分配变量。
GlobalMemory.init {
val1 5
val2 "some string"
}
这适用于运行DSL的简单VM。这适用于此代码
class GlobalMemory
include Singleton
def self.init &blk
GlobalMemory.instance.allocate &blk
end
def method_missing sym,*args, &blk
@segments[sym]=args[0]
end
def allocate &blk
self.instance_eval &blk
end
end
有没有办法允许val1=5(and val1 = 5)
?当我尝试这样做时,method_missing
不会触发,也不会出现错误消息。
答案 0 :(得分:1)
如果您执行以下操作,它将按原样运行:
GlobalMemory.init {
self.val3 = 'value'
}
否则它与本地变量声明无法区分。我想更好的方法是使用一个块参数并编写你的init方法:
GlobalMemory.init { |g|
g.val1 5
g.val2 "some string"
g.val3 = 'yeah'
}
我试图使用#local_variables来使var1 =解决方案工作时有点乱,但我最接近的就是:
class Foo
def initialize(&bl)
@data = {}
b = yield self
still_to_assign = eval('local_variables', b) - eval('local_variables', bl)
still_to_assign.each { |v| r = eval(v,b); @data[v] = r }
end
end
Foo.new {
one = 1
two = 2
three = 3
binding
}
如您所见,它要求您在块的末尾返回绑定对象。它还存在一些已经在块之前声明的变量的问题。也许有人可以建议一个更好的方法来做到这一点?
答案 1 :(得分:1)
我认为不可能像内部DSL那样干净利落地进行这项工作