21

私は「メタプログラミングRuby」という本からRubyオブジェクトモデルを研究しており、クラスがオブジェクトであるという概念も理解しています。

class A
end

A.ancestors # => [A, Object, Kernel, BasicObject]
A.class.ancestors # => [Class, Module, Object, Kernel, BasicObject]

私が混乱しているのは、最初にirbでA.ancestorsを試したときに、A.class.ancestorsで得られた結果を期待していたことです。私の思考プロセスは次のとおりです。Aはクラスであり、クラスはクラスクラス、その祖先はクラスです。しかし、ClassはAの祖先ではないようです。

誰かがここで私の混乱を解消することができるでしょうか?

4

1 に答える 1

23

クラスAはのインスタンスでありClass、を介してそれを見ることができますA.class

Aのインスタンスのクラスはであり、Aを介してそれにアクセスしますa = A.new; a.class

このメソッドancestorsは、そのクラスのオブジェクトがその継承として持つ(または持つであろう)クラス階層を示しています。

あなたの例では2つの並列クラス階層モデルが進行中ですが、Rubyはそのクラスを検査および変更するためのオブジェクトとして表すため、それらは互いに衝突するだけです。

A.class.ancestorsとA.ancestorsを交差させる必要がある基本的な理由はありません。ただし、Rubyには単純なルートを持つ深いクラスモデルもあるため、実際にはそれが表示されます。

実際、私は反例を見つけることができませんでした、nilでさえこれをします:

NilClass.ancestors
 => [NilClass, Object, Kernel, BasicObject]

NilClass.class.ancestors
 => [Class, Module, Object, Kernel, BasicObject]

しかし、これはより啓発的です:

BasicObject.ancestors
 => [BasicObject]

BasicObject.class.ancestors
 => [Class, Module, Object, Kernel, BasicObject]
于 2013-03-15T13:23:42.767 に答える