'yield self' 与 instance_eval 相同吗? [英] Is 'yield self' the same as instance_eval?

查看:49
本文介绍了'yield self' 与 instance_eval 相同吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果你用 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

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

In either case you can do this:

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

所以 'yield self' 意味着 Foo.new 之后的块总是在 Foo 类的上下文中求值.

So 'yield self' means that the block after Foo.new is always evaluated in the context of the Foo class.

这是正确的吗?

推荐答案

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

Your two pieces of code do very different things. By using instance_eval you're evaluating the block in the context of your object. This means that using def will define methods on that object. It also means that calling a method without a receiver inside the block will call it on your object.

在产生 self 时,您将 self 作为参数传递给块,但由于您的块不接受任何参数,因此它被简单地忽略.因此,在这种情况下,yield self 与不产生任何东西的作用相同.def 这里的行为与块外的 def 完全一样,yield self 实际上不会改变你定义方法的内容.你可以做的是:

When yielding self you're passing self as an argument to the block, but since your block doesn't take any arguments, it is simply ignored. So in this case yielding self does the same thing as yielding nothing. The def here behaves exactly like a def outside the block would, yielding self does not actually change what you define the method on. What you could do is:

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

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

The difference to instance_eval being that you have to specify the receiver explicitly.

编辑以澄清:

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

In the version with yield, obj in the block will be the object that is yielded, which in this case is is the newly created Foo instance. While self will have the same value it had outside the block. With the instance_eval version self inside the block will be the newly created Foo instance.

这篇关于'yield self' 与 instance_eval 相同吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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