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