2

ruby 1.9.3では、なぜFoo.explicit_receiver「保護されたメソッドと呼ばれる」エラーが発生するのですか?

私はこれらのチュートリアルを参照しています:

どの状態:

privateと同様に、暗黙のレシーバーを使用して保護されたメソッドをいつでも呼び出すことができますが、さらに、このレシーバーがselfまたはselfと同じクラスのオブジェクトである限り、明示的なレシーバーを使用して保護されたメソッドを呼び出すことができます。

私はFooインスタンスでprotectedを呼び出しています。これにより、protectedメソッドを呼び出すことができます。私は間違いなく何かが欠けています:)

コード例

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 に答える