在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) 

似乎在方法test1test2i的值在定义期间没有被替换,而是在调用方法时直接在现场计算。 所以我们只看到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所关联的问题