web-dev-qa-db-ja.com

誰かがClass.superclass.class.superclassのパラドックスを説明できますか?

それはおそらくパラドックスではありませんが、初心者の観点からは、確かにそのように思われます。

> Class.superclass
=> Module
> Class.superclass.class
=> Class
> Class.superclass.class.superclass
=> Module

つまり、クラスの親はモジュールですが、モジュールはクラスですか?

どうすればこれを理解できますか?

28
Nathan

TL; DR:モジュールはのスーパークラスクラスです。モジュールはのインスタンスクラスです。


Rubyのすべてのクラスには1つのスーパークラス*があります。

enter image description here

*スーパークラスを持たないBasicObjectを除く。

上記の図を次のように読んでください。FloatのスーパークラスはNumericです。 NumericのスーパークラスはObjectなどです。

オブジェクトをインスタンス化すると、そのオブジェクトはあるクラスのインスタンスになります。たとえば、「Nathan」はStringクラスのインスタンスです。 「ジョー」や「ジョン」もそうです。 1はFixnumクラスのインスタンスであり、2、3、4なども同様です。

enter image description here

上記の図を次のように読んでください。「Joe」はStringのインスタンスです。 1はFixnumなどのインスタンスです。

そうですね、Rubyでは、他のほとんどの言語とは異なり、Classは単なる別のクラスであり、FixnumやStringと同じようにインスタンス化することもできます。

enter image description here

上記の図を次のように読んでください。0.01はFloatのインスタンスです。文字列はクラスなどのインスタンスです。

「Nathan」がStringのインスタンスであるのと同じように、FixnumがClassのインスタンスであることを認識してください。 「John」がStringのインスタンスであるように、Floatは単なるClassのインスタンスです。すべてのクラスは、クラス自体でさえ、クラスの単なるインスタンスです!

アプリで新しいクラスを作成するときは常に、Hash.newが新しいハッシュをインスタンス化するのと同じように、クラスがClassである新しいオブジェクトをインスタンス化するか、「Nathan」が新しい文字列をインスタンス化します。

# By running this, you will be instantiating a new Class, and 
# it will be named Post 
class Post < ActiveRecord::Base
end

# Here is another perfectly valid way to write the above code:
Post = Class.new(ActiveRecord::Base)

# you can even instantiate a Class without giving it an explicit name:
x = Class.new(ActiveRecord::Base)

# and since your new things are classes, they can be instantiated
obj1 = Post.new
obj2 = x.new

さらに、ModuleはClassの単なる別のインスタンスです。アプリで新しいモジュールを作成するときはいつでも、新しいモジュールをインスタンス化するだけです。

# this will instantiate a new Module, and assign it to Foo
module Foo
end

# Here is another perfectly valid way to write the above code:
Foo = Module.new

# you can even instantiate a Module without giving it an explicit name.
m = Module.new

余談ですが、モジュールはメソッドと定数の単なるコレクションです。クラスもメソッドと定数のコレクションですが、インスタンス化できる機能が追加されています。モジュールをインスタンス化できません。あれは、 m.new 動作しないでしょう。

したがって、上の図に戻ると、質問に直接答えることができます。

つまり、クラスの親はモジュールですが、モジュールはクラスですか?

上の図からわかるように、モジュールはのスーパークラスクラスです。

下の図から:モジュールはのインスタンスクラスです。

73
John Douthat

2番目の例Class.superclass.classでは、Module.classを呼び出しています。 Moduleは、クラス、Moduleクラスを指します。

AnyClass.superclass.classは、BasicObject.superclass.classを除いて、クラスを返します。

クラスとインスタンスの区別は重要です。 BasicObjectはクラスです。これはnilを拡張するクラスであり、スーパークラスがないことを示すための空想的な言い方です。それは木の根です。 EVERYTHINGはオブジェクトです。これは、すべてが何らかのクラスのインスタンスであるという別の言い方です。

文字列の例

"Nathan" is an object.
"Nathan" is an instance of the String class.
"Nathan" is not a class.
"Nathan" has no superclass, because "Nathan" is not a class.

String is an object.
String is an instance of the Class class.
String's superclass is Object.

Object is an object.
Object is an instance of the Class class.
Object's superclass is BasicObject.

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject's superclass is nil.

nil is an object.
nil is an instance of the NilClass class
nil has no superclass, because it is not a class.

Fixnumの例

1 is an object.
1 is an instance of the Fixnum class.
1 is not a class.
1 has no superclass, because it is not a class.

Fixnum is an object.
Fixnum is an instance of the Class class.
Fixnum's superclass is Integer.

Integer is an object.
Integer is an instance of the Class class
Integer's superclass is Numeric.

Numeric is an object.
Numeric is an instance of the Class class.
Numeric's superclass is Object.

# everything below here is in the above example.
Object is an object.
Object is an instance of the Class class.
Object's superclass is BasicObject.

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject's superclass is nil.

nil is an object.
nil is an instance of the NilClass class
nil has no superclass, because it is not a class.

だから、最後に:

Class is an object.
Class is an instance of the Class class. # this is probably the most important part.
Class's superclass is Module # 2nd most important part

Module is an object
Module is an instance of the Class class. # 3rd
Module's superclass is Object # 4th

# everything below here is in the above examples.
Object is an object.
Object is an instance of the Class class.
Object's superclass is BasicObject.

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject's superclass is nil.

nil is an object.
nil is an instance of the NilClass class
nil has no superclass, because it is not a class.

表形式:

enter image description here

そして、それがすべて真実であることを確認したい場合は、Rubyで実行できます。

"Nathan".is_a?(BasicObject) # => true    "Nathan" is an object.
"Nathan".class #=> String                "Nathan" is an instance of the String class.
"Nathan".is_a?(Class) #=> false          "Nathan" is not a class.
"Nathan".superclass # NoMethodError      "Nathan" has no superclass, because "Nathan" is not a class.

String.is_a?(BasicObject) #=> true       String is an object.
String.class #=> Class                   String is an instance of the Class class.
String.superclass #=> Object             String's superclass is Object.

Object.is_a?(BasicObject) #=> true       Object is an object.
Object.class #=> Class                   Object is an instance of the Class class.
Object.superclass #=> BasicObject        Object's superclass is BasicObject.

BasicObject.is_a?(BasicObject) #=> true  BasicObject is an object.
BasicObject.class #=> Class              BasicObject is an instance of the Class class
BasicObject.superclass #=> nil           BasicObject's superclass is nil.

nil.is_a?(BasicObject) #=> true          nil is an object.
nil.class #=> NilClass                   nil is an instance of the NilClass class
nil.superclass # NoMethodError           nil has no superclass, because it is not a class.

そしてクラスから始めます:

Class.is_a?(BasicObject) #=> true        Class is an object.
Class.class #=> Class                    Class is an instance of the Class class. # this is probably the most important part.
Class.superclass #=> Module              Class's superclass is Module # 2nd most important part

Module.is_a?(BasicObject) #=> true       Module is an object
Module.class #=> Class                   Module is an instance of the Class class. # 3rd
Module.superclass #=> Object             Module's superclass is Object # 4th

Object.is_a?(BasicObject) #=> true       Object is an object.
Object.class #=> Class                   Object is an instance of the Class class.
Object.superclass #=> BasicObject        Object's superclass is BasicObject.

BasicObject.is_a?(BasicObject) #=> true  BasicObject is an object.
BasicObject.class #=> Class              BasicObject is an instance of the Class class
BasicObject.superclass #=> nil           BasicObject's superclass is nil.

nil.is_a?(BasicObject) #=> true          nil is an object.
nil.class #=> NilClass                   nil is an instance of the NilClass class
nil.superclass # NoMethodError           nil has no superclass, because it is not a class.
15
John Douthat