3

obj.methodルビーが次のように検索する原因methodになったという印象を受けました。

  1. のシングルトンobjクラスを調べます。
  2. objのシングルトン クラスに含まれるモジュールを調べます。
  3. objさんのクラスを見てください。
  4. objのクラスに含まれるモジュールを調べます
  5. クラスのスーパークラスが見つかるまで、手順 3 と 4 を繰り返します。
  6. method_missing見つからない場合は、元のオブジェクト を呼び出しますobj

このモデルでは、メソッドを検索する唯一のシングルトン クラスは、元のレシーバーのシングルトン クラス ですobj。ただし、このモデルでは、サブクラスがそのスーパークラスのシングルトン メソッドにアクセスできるという事実を説明できません。例えば

class Foo
  def self.foo
    "foo"
  end
end

class Bar < Foo
end

Bar.foo  #=> "foo"

Fooこれは、ある時点でシングルトン クラスがメソッドを検索することを意味すると信じているため、私は混乱していfooます。ただし、上記のモデルでは、Barのシングルトン クラスのみが検索されると予想されfooます。Barそれができなければ、ルビーがのクラスを調べClass、スーパークラス チェーンをクロールし続ける (Fooおよびそのシングルトン クラスを完全にスキップする)ことを期待します。

だから私の質問: クラスがそのスーパークラスのシングルトン メソッドにアクセスできるという事実を説明する Ruby メソッド ルックアップの私の理解に欠けているものは何ですか?

4

2 に答える 2

8

サブクラス化する場合、にBar.superclass設定されるだけでなくFoo、シングルトンクラスにも同じことが当てはまります。

Bar.singleton_class.superclass == Foo.singleton_class  # => true

だからあなたは本当に混乱していません。実際のルックアップは次のとおりです。

  1. objのシングルトンクラスから始めます。
  2. 祖先リストでインスタンスメソッドを探します。
    • 付加されたモジュール(Ruby 2.0)
    • クラス自体
    • 含まれているモジュール
  3. スーパークラスで#2を繰り返します。
  4. #1を繰り返しますが、今回は探していますmethod_missing
于 2012-07-09T17:50:53.753 に答える
3

それはかなり簡単です。または実際にはそうではありませんが、とにかく:

The metaclass of the superclass is the superclass of the metaclass.

ここで、「メタクラス」は実際には「シングルトンクラス」です。モデルに欠けているのはBar.superclass継承Foo.superclassです。簡潔でシンプル :)

于 2012-07-09T18:02:31.590 に答える