我在Ruby中使用DSL元编程。
以下程序使用嵌套块评估按预期工作;它的含义对于我在这里暴露的问题并不重要。我所遇到的“错误”或麻烦涉及最后四行:
# works (using a variable 'mm' to store the result of Gen.define method)
mm=Gen.define("abc") do
node(:func){}
end
pp mm
# returns {"abc"=>#<Definition:0x000000021f6c90 @nodes={:func=>#<Node:0x000000021f6a60 @name=:func>}>}
但以下不起作用,返回错误,如下所示。不同之处在于,define(哈希)的结果在这里直接作为参数传递给'pp'漂亮的打印机,而工作程序使用变量(mm)。
# does NOT work (no variable)
pp Gen.define("abc") do
node(:func){}
end
为什么这种行为会有所不同?
错误是:
`instance_eval':未提供块(ArgumentError)
这是完整的(工作)程序(同样它没有做任何有用的事情)。
require 'pp'
class Gen
def self.define name,&block
@nodes=Definition.new(&block)
return name => @nodes
end
end
class Definition
def initialize(&block)
@nodes={}
instance_eval(&block)
end
def node name,&block
@nodes.merge!(name => Node.new(name,&block))
end
end
class Node
def initialize name,&block
@name=name
instance_eval(&block)
end
end
mm=Gen.define("abc") do
node(:func){}
end
pp mm
答案 0 :(得分:1)
这里的问题只是优先权:当你说
时pp Gen.define("abc") do
node(:func){}
end
它是pp
获得阻止。这与:
pp(Gen.define("abc")) do
node(:func){}
end
这将做你想要的:
pp(Gen.define("abc") do
node(:func){}
end)
有些人(包括我)建议在方法返回值时使用大括号而不是do
... end
作为块。您可能会发现这会给您带来不太令人惊讶的结果:
pp Gen.define("abc") {
node(:func){}
}