Подтвердить что ты не робот

Может ли кто-нибудь объяснить парадокс Class.superclass.class.superclass?

Это, вероятно, не парадокс, а с точки зрения новичков, похоже, это так.

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

Итак, родитель класса - это модуль, но модуль - это класс?

Как я могу это понять?

4b9b3361

Ответ 1

TL; DR: модуль суперкласс класса. Модуль экземпляр класса.


Позвольте мне попытаться объяснить это более четко. Пожалуйста, простите мои рукописные рисунки - у меня нет никакого привлекательного программного обеспечения для рисования.

Каждый класс в Ruby имеет 1 суперкласс *.

enter image description here

* За исключением BasicObject, который не имеет суперкласса.

Прочитайте приведенный выше рисунок следующим образом: Суперкласс Float является числовым. Суперкласс Numeric - это Object и т.д.

Когда вы создаете экземпляр объекта, объект будет экземпляром некоторого класса. Например, "Натан" является экземпляром класса 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. Строка - это экземпляр класса и т.д.

Поймите, что Fixnum является экземпляром класса, так же, как "Nathan" является экземпляром String. Так же, как "Джон" - это экземпляр String, Float - это всего лишь экземпляр класса. Каждый класс является просто экземпляром класса, даже самого класса!

Всякий раз, когда вы пишете новый класс в своем приложении, вы просто создаете экземпляр нового объекта, класс которого является классом, точно так же, как Hash.new создает новый Hash, или "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

Кроме того, модуль - это еще один пример класса. Всякий раз, когда вы пишете новый модуль в своем приложении, вы просто создаете новый модуль.

# 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 не будет работать.

Итак, вернемся к верхней графике, на ваш вопрос можно ответить напрямую:

Итак, родитель класса - это модуль, но модуль - это класс?

Вы можете видеть из верхнего графика: Модуль суперкласс класса.

Из нижнего графика: Модуль экземпляр класса.

Ответ 2

В вашем втором примере Class.superclass.class вы вызываете Module.class. Модуль относится к классу, классу модуля.

AnyClass.superclass.class вернет класс, за исключением BasicObject.superclass.class

Важное значение имеет различие между классом и экземпляром. BasicObject - это класс. Это класс, который расширяет ноль, что является причудливым способом сказать, что у него нет суперкласса. Это корень дерева. ВСЕ - это объект, который является еще одним способом сказать, что все является экземпляром некоторого класса.

Пример строки

"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 superclass is Object.

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

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject 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 superclass is Integer.

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

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

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

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject 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 superclass is Module # 2nd most important part

Module is an object
Module is an instance of the Class class. # 3rd
Module 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 superclass is BasicObject.

BasicObject is an object.
BasicObject is an instance of the Class class
BasicObject 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 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 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 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 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 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 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 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.