1

Ruby の研究を続けていると、別の疑問が生じました。クラスでクラスメソッドを定義すると、そのメソッドの定義を取得するシングルトンクラスが作成され、それ以降、そのメソッドはそのシングルトンクラスのインスタンスメソッドになることを知っています(テストからこの結論を得ましたが、間違っているかもしれませんので、お気軽に訂正してください)。

私の質問は、メソッドがそのクラスのインスタンスメソッドとしてシングルトンクラスで定義されている場合、X.classMethodを使用してクラスXでクラスメソッドを呼び出すにはどうすればよいですか.)。クラスのシングルトンクラスは、それが由来するクラスと階層的に関連していないことに気付いたので(いくつかのテストを実行して)、さらに混乱します。クラスメソッド呼び出しはシングルトンクラスにどのように解決されますか? より正確には、インスタンスなしで、インスタンスメソッドであるシングルトンクラスのメソッドを呼び出すクラスはどうですか。

私はあなたを混乱させなかったことを願っています。

もう一度ありがとう。

4

2 に答える 2

2

以下の例から始めます。

class Foo
  def self.bar
    puts 12
  end
end

Foo.singleton_methods # => [:bar]
Foo.ancestors # => [Foo, Object, Kernel, BasicObject]

Ruby ではクラスもオブジェクトです。ここ#barに のシングルトン メソッドがありFooます。あなたがしたときFoo.barFoo最初にそのシングルトンクラスで検索し、次に祖先チェーンシングルトンクラスを検索しました。シングルトン クラスは一種のゴースト クラスであるため、祖先チェーンには表示されませんが、存在します。Foo.ancestorsこれは、言語設計者によって意図的にの出力から隠されています。singleton メソッドはオブジェクト (ここではFOO ) によって直接呼び出され、singleton (オブジェクトごとの基底クラス) クラスが作成されます。シングルトン クラスのインスタンスを作成することはできません。

ここに証明があります:

Foo.singleton_class.new # can't create instance of singleton class (TypeError)

また、クラスのシングルトン メソッドは here と言いBar、その子孫クラス (here Foo) でも使用できることを覚えておいてください。Barのメタクラスが のメタクラスのスーパークラスFooになったので、 と書くとclass Foo < Bar...

class Bar
  def self.biz
    puts 11
  end
end

class Foo < Bar
  def self.bar
    puts 12
  end
end

Bar.singleton_class # => #<Class:Bar>
Foo.singleton_class.superclass # => #<Class:Bar>
于 2014-02-09T21:47:24.950 に答える
1

最初の質問に対して、クラス X が次のものを含むものであると仮定します。

class X
  def self.class_method
  end
end

次にclass_methodのインスタンス メソッドですX.singleton_class。実行することで確認できます。

X.singleton_class.instance_methods(false)
# ==> [:class_method]

シングルトン クラスがクラス階層にどのように関連しているかを確認するには、次のような図が役に立ちました (eigenclass はシングルトン クラスの別の名前です)。

ここに画像の説明を入力

その図の後、少し複雑だと思いましたが、論理を使用すると、次の仮定が成り立つと仮定すると、より必要なようです。

  1. すべてがオブジェクトです
  2. すべてのオブジェクトにはクラスがあります
  3. クラスは、他のクラスにはないメソッドを持つことができます

1 からクラスはオブジェクトであると推測でき、2 からクラスにはクラスが必要であると推測できます。しかし、3 を満たすには、クラスが他のクラスからアクセスできないメソッドを持つことができるように、Xとの間に何らかのクラスが必要です。Classシングルトン クラスは、これら 3 つの仮定の必然的な結果です。

于 2014-02-09T21:49:46.373 に答える