ruby - 'yield self' 和 instance_eval 一样吗?

标签 ruby

如果用 instance_eval: 定义 Foo 有什么不同吗? . .

class Foo
    def initialize(&block)
      instance_eval(&block) if block_given?
    end
  end

<强>。 . .或者使用“yield self”:

class Foo
  def initialize
    yield self if block_given?
  end
end

无论哪种情况,您都可以这样做:

x = Foo.new { def foo; 'foo'; end }
x.foo 

所以“yield self”意味着 Foo.new 之后的 block 总是在 Foo 类的上下文中求值。

这是正确的吗?

最佳答案

您的两段代码做的事情截然不同。通过使用 instance_eval,您可以在对象的上下文中评估 block 。这意味着使用 def 将在该对象上定义方法。这也意味着在 block 内调用没有接收器的方法将在您的对象上调用它。

当 yield self 时,您将 self 作为参数传递给 block ,但由于您的 block 不接受任何参数,因此它会被忽略。所以在这种情况下,屈服 self 与不屈服任何东西一样。 def 在这里的行为与 block 外的 def 完全一样,yield self 实际上并没有改变你定义方法的内容。你可以做的是:

class Foo
  def initialize
    yield self if block_given?
  end
end
x = Foo.new {|obj| def obj.foo() 'foo' end}
x.foo

与 instance_eval 的区别在于您必须明确指定接收者。

编辑澄清:

在有 yield 的版本中,block 中的 obj 将是被 yield 的对象,在本例中是新创建的 Foo 实例。虽然 self 将具有与 block 外相同的值。 block 内的 instance_eval 版本 self 将是新创建的 Foo 实例。

关于ruby - 'yield self' 和 instance_eval 一样吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1425055/

相关文章:

ruby-on-rails - 结束 haml 评论

ruby - 如何找到 ruby 中两个时间之间的差异?

ruby - (Ruby) 是否有一个函数可以轻松找到字符串中的第一个数字?

ruby-on-rails - 如何在 RoR 中使用 content_tag 嵌入标签?

mysql - 在 Fedora 上安装 MySQL gem 时出现问题

mysql - 使用 activerecord ruby​​ 计数不同

ruby-on-rails - 获取语​​法错误,输入意外终止

windows - 手动安装 Ruby 1.8.7(和其他东西)

ruby-on-rails - 设计自定义登录表单

ruby-on-rails - 在rails中批量上传大文件