在define_method中使用局部变量
我想了解define_method
如何工作以及如何正确使用定义块之外的变量。 这是我的代码:
class Test def self.plugin for i in 1..2 define_method("test#{i}".to_sym) do pi 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
的最新值, i
2
。 但Ruby从哪里获取此值? 有没有办法让test#{i}
打印出来?
在这种特殊情况下,我可以使用__method__
进行解决方法 ,但可能有更好的解决方案。
正如在注释中提到的那样,这取决于闭包 – 传递给define_method
的块从其范围中捕获局部变量(而不仅仅是它们发现的值)。
for
不会创建新范围,因此您的方法会“看到”对i
的更改。 如果您使用块(例如每个块),则会创建一个新范围,但这不会发生。 您只需将代码更改为
class Test def self.plugin (1..2).each do |i| define_method("test#{i}".to_sym) do pi end end end plugin end
这基本上是Arup所关联的问题