2012-05-11 70 views
28

To chyba nie jest paradoks, ale z perspektywy nowicjuszy na pewno tak.Czy ktoś może wyjaśnić paradoks Class.superclass.class.superclass?

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

Więc rodzicem klasy jest moduł, ale moduł jest klasą?

Jak mogę to zrozumieć?

+2

Możliwe duplikat [klasy/Przedmiot paradoksem splątanie] (http://stackoverflow.com/questions/7675774/the-class-object-paradox-confusion). Zobacz także [Ruby metaclass confusion] (http://stackoverflow.com/questions/10525053/ruby-metaclass-confusion). –

+1

To są świetne referencje. Dzięki, że wskazałeś im Andrew. – Nathan

+0

Dziękuję za wskazanie! –

Odpowiedz

71

TL; DR: Moduł jest się nadklasa klasy. Moduł to instancja klasy.


Pozwólcie, że spróbuję wyjaśnić to dokładniej. Proszę wybaczyć moje odręczne rysunki - nie mam żadnych wymyślnych programów do rysowania.

Każda klasa w Rubim ma 1 nadklasę *.

enter image description here

* Z wyjątkiem BasicObject, która nie posiada superklasę.

Przeczytaj powyższą grafikę w następujący sposób: Nadklasa Float jest numeryczna. Nadklasy Numeric to Object, etc ...

Po instancję obiektu, obiekt będzie instancją pewnej klasy. Na przykład "Nathan" jest instancją klasy String. Tak samo jest z "Joe" lub "John". 1 jest instancją klasy Fixnum, podobnie jak 2, 3, 4, itd ...

enter image description here

Czytaj powyższą grafikę tak: "Joe" jest instancją String. 1 jest instancją Fixnum, itd ...

Cóż, w Ruby, w przeciwieństwie do większości innych języków, Class jest po prostu kolejną klasą, i może być również utworzona, podobnie jak Fixnum lub String.

enter image description here

Czytaj powyższą grafikę takiego: 0,01 jest instancją pływaka. String jest instancją klasy, etc ...

Zrozum, że Fixnum jest instancją klasy, podobnie jak „Nathan” jest instancją String. Podobnie jak "John" jest instancją String, Float jest tylko instancją klasy. Każda klasa to tylko przykład klasy, nawet sama klasa!

Zawsze, gdy piszesz nową klasę w swojej aplikacji, po prostu tworzysz nowy obiekt, którego klasą jest Klasa, podobnie jak Hash.new tworzy nowy Hash, lub "Nathan" tworzy nowy ciąg.

# 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 

Co więcej, moduł jest kolejnym przykładem klasy. Za każdym razem, gdy piszesz nowy moduł w swojej aplikacji, właśnie tworzysz nowy moduł.

# 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 

Na bok: Moduł to tylko zbiór metod i stałych. Klasy są również zbiorem metod i stałych, ale z dodatkową funkcjonalnością możliwości tworzenia instancji. Nie można utworzyć instancji modułu. Oznacza to, że m.new nie będzie działać.

Tak, nawiązując do górnej grafiki, Twoje pytanie można odpowiedzieć wprost:

Więc dominująca klasa jest moduł, ale moduł jest klasa?

Widać z górnej grafiki: Moduł jest nadklasy klasy.

Od dołu grafika: Moduł to instancja klasy.

+0

Wow, bardzo pomocne. Zmieniłem wybraną odpowiedź na tę, ale obie odpowiedzi, które podałeś, pomogły mi. – Nathan

+0

Ten temat zasługuje na pełną dyskusję, która ma wiele stycznych - niestety Stack Overflow nie zapewnia dobrego forum dla tego typu rzeczy. Ostatecznie jednak moim odejściem jest to, że między obiektem a klasą zachodzi okrężna logika. Z perspektywy laików (programowałem przez całe ~ 5 miesięcy), moim zdaniem jest to, że ponieważ Ruby jest zaimplementowany w C, to jest również tworzone w C. A podczas tego wystąpienia powstaje okrągła logika. Mam nadzieję, że jestem na dobrej drodze. – Nathan

+1

@@ Nathan Widać z górnej grafiki: Moduł jest nadklasą klasy. Z dolnej grafiki: Moduł jest instancją klasy. ** To działa w sposób okrągły **. Myślę, że to jest ważny punkt – SamFlushing

15

W swoim drugim przykładzie Class.superclass.class, dzwonisz Module.class. Moduł odnosi się do klasy, klasy Module.

AnyClass.superclass.class powróci Class, z wyjątkiem BasicObject.superclass.class

rozróżnienie między klasą a instancją jest ważne. BasicObject to klasa. Jest to klasa, która rozszerza zero, co jest fantazyjnym sposobem powiedzenia, że ​​nie ma żadnej nadklasy. To jest korzeń drzewa. WSZYSTKO jest obiektem, który jest innym sposobem powiedzenia, że ​​wszystko jest instancją jakiejś klasy.

Przykład ciąg

przykład
"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. 

Tak więc, na koniec:

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. 

w postaci tabeli:

enter image description here

A jeśli chcesz sprawdzić, czy to wszystko prawda, wystarczy uruchomić go w 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. 

I począwszy od klasy:

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. 
+0

Może co mnie mylące jest to, że każdy powtarza wszystko jest obiektem, ale kiedy robię BasicObject.class zwraca klasę. Tak więc jestem zdezorientowany, jak zrozumieć, czym jest "klasa". Jeśli klasa BasicObject ma klasę, to czy nie wszystko jest klasą, a nie obiektem? – Nathan

+0

Lol, to zaczyna się czuć jak filozofia 101, nieporuszony ruch Arystotelesa i tak dalej. Więc jeśli wszystko jest obiektem (instancją klasy), to co z BasicObject? BasicObject.class => Klasa. Class.class => Klasa. Jednak gdy przejdziesz w łańcuch do zera, otrzymasz nil.class => NilClass i NilClass.class => Class. Jeśli więc wszystko jest przedmiotem (instancją klasy), to jaka jest początkowa klasa, z której wszystko powstaje - i jak powstaje? – Nathan

+0

Tak więc, z wyjątkiem 'nil' i twoich własnych obiektów niestandardowych, wszystko jest instancją klasy Class - włączając Class. Ponadto istnieje klasa o nazwie Module, której nadklasą jest Object. Moduł jest nadklasą klasy. Co oznacza, że ​​Object jest klasą super-duperów klasy. Czy to brzmi poprawnie? Jeśli tak, to pozostaje tylko zastanowić się, w jaki sposób obiekt może być instancją klasy, ale klasa (poprzez moduł) jest dzieckiem obiektu? – Nathan

Powiązane problemy