ruby-on-rails - 为什么 class_eval 以不同的方式评估字符串和 block ?

标签 ruby-on-rails ruby metaprogramming

我是 ruby​​ 的新手,今天我发现了 class_eval 的一些不同行为用于字符串和块。例如

class A
end

class C
  A.class_eval("print Module.nesting") # [A, C]
  A.class_eval{print Module.nesting} # [C]
end
正如您在字符串 Module.nesting 的情况下所见打印 [A,C],而在块的情况下,它只打印 C。
你能告诉我这是什么原因吗?

最佳答案

在第一种情况下,您将一个字符串填充到 class_eval 中。 ,并且这个 class_eval 是在类 A 上调用的。因此,当计算表达式时,Module.nesting - 需要产生嵌套层级 - 发现自己在 A 中,依次在 C 内进行评估.
在第二种情况下,您传递一个块,它类似于 proc 对象。效果堪比

 class C
   p = Proc.new { print Module.nesting }
   do_something(p)
 end
Proc 代表一个闭包,即上下文是创建 Proc 的上下文。很明显,这里的嵌套只是 C,如果你在 do_something 中计算 p,这不会改变。 .
这是一件好事。想象一下以下情况:
def f(p)
  x = 'f'
  p.call
end

def g
  x = 'g'
  p = Proc.new { puts x }
  f(p)
end
因为 p 的绑定(bind)发生在方法 g 内部,所以块中引用的 x 指的是本地值 xg ,虽然 f有一个同名的局部变量。因此,g 在这里打印。以同样的方式,在您的示例中重现了块定义点的嵌套。

关于ruby-on-rails - 为什么 class_eval 以不同的方式评估字符串和 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68058552/

相关文章:

ruby-on-rails - 如何根据多个字段对行进行分组?

ruby-on-rails - ActiveRecord 查询链

ruby-on-rails - 安装mysql(2.9.1)时出错,Bundler无法继续

ruby - 将参数传递给初始化和在初始化中设置它们有什么区别?

ruby - splat 运算符在没有变量名时会做什么?

python - 在python中动态构建类型

ruby-on-rails - 如何将单个列的值放入数组中

ruby-on-rails - 在 number_to_currency 中使用基于十进制值的动态精度值

ruby - "target.should be"如何在rspec中工作

c++ - 是否可以使用 C++ 元编程收集一个特定模板的所有显式实例化类型?