ruby - class_eval、class_exec、module_eval 和 module_exec 之间有什么区别?

标签 ruby

我正在阅读 Module 文档,但似乎无法理解它们之间的差异以及应该在何处使用。

evalexec 有何不同?

最佳答案

我将通过在您的问题中包含 instance_{eval|exec} 来回答您的问题。

{instance|module|class}_{eval|exec} 的所有变体都会更改当前上下文,即 self 的值:

class Array
  p self                     # prints "Array"
  43.instance_eval{ p self } # prints "43"
end

现在说说区别。 eval 版本接受字符串或 block ,而 exec 版本只接受 block 但允许您向其传递参数:

def example(&block)
  42.instance_exec("Hello", &block)
end
example{|mess| p mess, self } # Prints "Hello" then "42"

eval 版本不允许传递参数。它提供 self 作为第一个参数,尽管我想不出它的用途。

最后,module_{eval|exec}和对应的class_{eval|exec}是一样的,只是和instance_{eval有一点点区别|exec 因为它们以不同的方式改变当前打开的类(即 def 会影响什么):

String.instance_eval{ def foo; end }
Integer.class_eval  { def bar; end }

String.method_defined?(:foo)            # => false
String.singleton_methods.include?(:foo) # => true
Integer.method_defined?(:bar)           # => true

所以obj.instance_{eval|exec}开启了obj的单例类,而mod.{class|module}_{eval|exec} 打开 mod 本身。

当然,instance_{eval|exec} 可用于任何 Ruby 对象(包括模块),而 {class|module}_* 仅可用于 模块(因此)

关于ruby - class_eval、class_exec、module_eval 和 module_exec 之间有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9057711/

相关文章:

ruby - 用 7n +1 填充 ruby​​ 中的数组

ruby - "\n"与 '\n' 的奇怪之处

ruby - 使用 Ruby 创建 Git 提交并推送到 GitHub

ruby-on-rails - 我应该创建两组不同的 'category' 模型吗? Rails 上的 Ruby

ruby-on-rails - 未定义的方法 `microposts'

java - java+python+ruby的持续构建框架?

ruby - 从 ruby​​ 中的字符串中的每一行中删除尾随空格

ruby - 用于在 ruby​​ 中提取哈希参数的库

ruby - rspec 与不同的 DNS 服务器

ruby - 使用 ruby​​ 读取视频文件元数据