Ruby で DSL メタプログラミングをいじっています。
次のプログラムは、ネストされたブロックの評価を使用して、期待どおりに動作します。その意味は、ここで公開する問題にとって重要ではありません。私が抱えている「バグ」または問題は、最後の 4 行に関するものです。
# 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' pretty printer に直接渡されるのに対し、作業プログラムは変数 (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