如果一个块是一个闭包,为什么这个代码不起作用,以及如何使它工作?
def R(arg)
Class.new do
def foo
puts arg
end
end
end
class A < R("Hello!")
end
A.new.foo #throws undefined local variable or method `arg' for #<A:0x2840538>
答案 0 :(得分:26)
块是闭包,arg
块内确实可以使用Class.new
。它在foo
方法中不可用,因为def
启动了新范围。如果您将def
替换为define_method
(需要一个块),您将看到所需的结果:
def R(arg)
Class.new do
define_method(:foo) do
puts arg
end
end
end
class A < R("Hello!")
end
A.new.foo # Prints: Hello!
答案 1 :(得分:5)
如果您动态定义类,可以根据需要更改它:
def R(arg)
c = Class.new
# Send the block through as a closure, not as an inline method
# definition which interprets variables always as local to the block.
c.send(:define_method, :foo) do
arg
end
c
end
class A < R("Hello!")
end
puts A.new.foo.inspect
# => "Hello!"