使用Ruby'pp'漂亮的打印机时出错(元编程测试中需要的变量)

时间:2013-10-04 12:00:52

标签: ruby metaprogramming

我在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

1 个答案:

答案 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){}
}