2

在 ruby​​ 1.9.3 中,为什么会Foo.explicit_receiver产生“受保护的方法调用”错误?

我正在参考这些教程:

哪一个州:

您始终可以使用隐式接收器调用受保护的方法,就像私有一样,但此外,您可以使用显式接收器调用受保护的方法,只要此接收器是 self 或与 self 相同的类的对象。

我用一个Foo实例调用受保护的,这应该允许我调用受保护的方法。我肯定错过了一些东西:)

代码示例

class Foo
  def implicit_receiver
    protected_method
  end

  def explicit_receiver
    self.protected_method
  end

  def self.explicit_receiver
    Foo.new.tap do |foo|
      foo.protected_method
    end
  end

protected

  def protected_method
    p "called protected method!"
  end
end

foo = Foo.new
foo.implicit_receiver
foo.explicit_receiver
Foo.explicit_receiver

# output
# "called protected method!"
# "called protected method!"
# protected.rb:12:in `explicit_receiver': protected method `protected_method' called for #<Foo:0x10a280978> (NoMethodError)
4

1 回答 1

3

受保护的方法可用于同一类或子类的其他实例的实例方法。但是,explicit_receiver引发错误的是类(实际上是元类)本身的单例方法,并且无法访问类的受保护实例方法。

您只需运行即可看到这一点:

class Foo
  def self.test
    Foo.new.protected_method
  end
end

Foo.test

你会得到一个类似的错误。

在这种情况下令人困惑的是,您正在调用tap您创建的实例并且仍然收到此错误。这是因为tap块的绑定仍在元类的上下文中,无法访问其类的受保护实例方法 - 您可以检查self该块内部以查看这一点。

于 2013-01-01T21:59:33.847 回答