在define_method中使用局部变量 [英] Using local variables in define_method
问题描述
我想了解define_method
的工作原理以及如何在定义块之外正确使用变量.这是我的代码:
I would like to understand how define_method
works and how to properly use the variables outside of the definition block. Here is my code:
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
?
It seems that in the methods test1
and test2
, the value of i
is not substituted during the definition, but is computed directly on the spot when the method is called. So we see only the latest value of i
, which is 2
. But where does Ruby take this value from? And is there a way to let test#{i}
print i
?
在这种情况下,我可以使用
In this particular case, I could do a workaround using __method__
, but probably there is a better solution.
推荐答案
正如注释中提到的,这归结为闭包-传递给define_method
的块从其范围中捕获局部变量(而不仅仅是您发现的局部变量的值)出去).
As mentionned in comments this is down to closures - the block passed to define_method
captures the local variables from its scope (and not just their value as you found out).
for
不会创建新的作用域,因此您的方法看到"对i
的更改.如果您使用一个块(例如,与每个块一起使用),则会创建一个新的作用域,并且不会发生这种情况.您只需要将代码更改为
for
doesn't create a new scope, so your method 'sees' the change to i
. If you use a block (for example with each) then a new scope is created and this won't happen. You just need to change your code to
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)所链接的问题
which is basically what the question linked by Arup was about
这篇关于在define_method中使用局部变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!