ruby - 变量如何绑定(bind)到 define_method 的主体?

标签 ruby reflection metaprogramming

在尝试提高我的 Ruby 技能时,我不断遇到这种情况,我无法通过阅读 API 文档来找出解释。一个解释将不胜感激。这是示例代码:

for name in [ :new, :create, :destroy ]
  define_method("test_#{name}") do
    puts name
  end
end

我想要/期望发生的是 name 变量将绑定(bind)到给定 define_method 的 block ,当 #test_new被称为它会输出"new"。相反,每个定义的方法输出“destroy”——分配给 name 变量的最后一个值。我对 define_method 及其 block 有什么误解?谢谢!

最佳答案

Ruby 中的 block 是闭包:您传递给 define_method 的 block 捕获变量 name 本身——而不是它的值——因此无论何时调用该 block ,它都保留在范围内.这是第一 block 拼图。

第二部分是define_method定义的方法 block 本身。基本上,它将 Proc 对象(传递给它的 block )转换为 Method 对象,并将其绑定(bind)到接收器。

所以你最终得到的是一个方法,它捕获(关闭)变量name,当你的循环完成时,它被设置为:销毁

补充: for ... in 构造实际上创建了一个新的局部变量,对应的[ ... ].each {|name| ... 构造将做。也就是说,您的 for ... in 循环等效于以下内容(无论如何在 Ruby 1.8 中):

name = nil
[ :new, :create, :destroy ].each do |name|
  define_method("test_#{name}") do
    puts name
  end
end
name # => :destroy

关于ruby - 变量如何绑定(bind)到 define_method 的主体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2029524/

相关文章:

ruby - 在 Ruby 中取消定义变量

ruby - Ruby 中的继承

java - 当我知道该类时如何正确调用方法?

java - 如何将 YAML 文件加载到案例类中?

c# - 反射能解决什么问题?

c++ - 可变参数模板异构容器

ruby - 如何使用 Ruby 模拟 Web session 并存储接收到的 cookie?

ruby-on-rails - 如何通过删除 Time.Now 对出生日期格式进行 Rspec 测试?

ruby-on-rails - 没有任何 gem 的 Facebook Graph API 调用

R 元编程 : return function body with arguments values filled in