wie tun, um diese Arbeit
Ganz einfach: es funktioniert nicht. Jedenfalls nicht in Ruby.
Genau wie in den meisten anderen Sprachen gibt es einige Kerneinheiten, von denen einfach angenommen wird, dass sie existieren. Sie fallen vom Himmel, materialisieren aus dünner Luft, erscheinen magisch.
In Ruby, einige dieser magischen Dinge sind:
Object
keine übergeordnete Klasse haben, aber man kann nicht eine Klasse ohne übergeordnete Klasse, die implizite direkte Ober definieren ist immer Object
. [Anmerkung: Es kann Implementierungs-definierte Superklassen von Object
geben, aber schließlich wird es einen geben, der keine Superklasse hat.]
Object
ist eine Instanz Class
, die eine Unterklasse von Object
(was die indirekt Object
bedeutet eine Instanz von Object
selbst) ist
Class
eine Unterklasse von Module
ist, die eine Instanz von Class
ist
Class
ist eine Instanz von Class
Keines dieser Dinge kann in Ruby erklärt werden.
BasicObject
, Object
, Module
und Class
alle müssen in die Existenz zugleich springen, weil sie zirkuläre Abhängigkeiten haben.
Nur weil diese Beziehung nicht in Ruby-Code ausgedrückt werden kann, bedeutet das nicht, dass die Ruby Language Specification nicht sagen kann, dass es so sein muss. Es liegt am Implementierer, einen Weg zu finden, dies zu tun. Schließlich hat die Ruby-Implementierung Zugriff auf die Objekte, die Sie als Programmierer nicht haben.
Zum Beispiel könnte die Ruby-Implementierung ersten BasicObject
schaffen, sowohl seine superclass
Zeiger und seine class
Zeiger auf null
Einstellung.
Dann schafft es Object
, seine superclass
Zeiger auf BasicObject
und seine class
Zeiger auf null
Einstellung.
Als nächstes erzeugt es Module
, seine superclass
Zeiger auf Object
und seine class
Zeiger auf null
Einstellung.
Schließlich schafft es Class
, seine superclass
Zeiger auf Module
und seine class
Zeiger auf null
Einstellung.
Jetzt können wir BasicObject
's, Object
' s, Module
's, und Class
' s class
Zeiger überschreiben zu Class
-zu-Punkt, und wir sind fertig.
Dies ist leicht von außerhalb des Systems zu tun, es sieht einfach komisch von innen.
Sobald sie tun existieren, ist es jedoch durchaus möglich, den Großteil ihres Verhaltens in einfachen Ruby zu implementieren. Sie brauchen nur sehr Barebone-Versionen dieser Klassen, dank der offenen Klassen von Ruby können Sie fehlende Funktionen zu einem späteren Zeitpunkt hinzufügen.
In Ihrem Beispiel wird die class Class
nicht Erstellen eine neue Klasse Class
genannt, wird die bestehenden Klasse Wiedereröffnung Class
, die wir von der Laufzeitumgebung gegeben wurde.
So ist es durchaus möglich, das Standardverhalten von Class#new
im Klar Ruby zu erklären:
class Class
def new(*args, &block)
obj = allocate # another magic thing that cannot be explained in Ruby
obj.initialize(*args, &block)
return obj
end
end
[Anmerkung:. Tatsächlich, initialize
privat ist, so dass Sie obj.send(:initialize, *args, &block)
verwenden müssen, die Zugriffsbeschränkung zu umgehen]
BTW: Class#allocate
ist ein weiteres dieser magischen Dinge. Es weist ein neues leeres Objekt in Rubys Objektraum zu, was in Ruby nicht möglich ist. Class#allocate
muss also auch vom Laufzeitsystem bereitgestellt werden.
'Class.class # => Class' – Flexoid
Es ist Schildkröten den ganzen Weg hinunter! –
Siehe auch [Die Paradox Verwirrung der Klasse/Objekt] (http://stackoverflow.com/questions/7675774/the-class-object-paradox-confusion). –