如果一个块是一个闭包,为什么这个代码不起作用,以及如何使它工作?
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>
Run Code Online (Sandbox Code Playgroud)
sep*_*p2k 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!
Run Code Online (Sandbox Code Playgroud)
如果动态定义类,可以根据需要更改它:
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!"
Run Code Online (Sandbox Code Playgroud)