在define_method中使用局部变量 [英] Using local variables in define_method

查看:99
本文介绍了在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)

似乎在方法test1test2中,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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆