我想了解define_method
如何工作以及如何正确使用定义块之外的变量。这是我的代码:
class Test
def self.plugin
for i in 1..2
define_method("test#{i}".to_sym) do
p i
end
end
end
plugin
end
ob = Test.new
ob.test1 #=> 2 (I would expect 1)
ob.test2 #=> 2 (I would expect 2)
似乎在方法test1
和test2
中,i
的值在定义期间未被替换,而是在调用方法时直接在现场计算。因此,我们只看到i
的最新值,即2
。但Ruby从哪里获取此值?有没有办法让test#{i}
打印i
?
在这种特殊情况下,我可以做workaround using __method__
,但可能有更好的解决方案。
答案 0 :(得分:6)
正如在评论中提到的,这取决于闭包 - 传递给define_method
的块从其范围捕获局部变量(而不仅仅是你发现的值)。
for
没有创建新的范围,因此您的方法会看到'对i
的更改。如果您使用块(例如每个块),则会创建一个新范围,但这不会发生。您只需将代码更改为
class Test
def self.plugin
(1..2).each do |i|
define_method("test#{i}".to_sym) do
p i
end
end
end
plugin
end
这基本上是Arup所关联的问题是关于