Die Programmiersprache Ruby (German Edition)
Unsere Klasse hat keine Klassenmethoden, daher wird hier nichts gefunden. Nach dem Suchen in der Eigenklasse sieht der Algorithmus im Klassenobjekt von
C nach
. Die Klasse von
C
ist
Class
, daher sucht Ruby als Nächstes nach Methoden in
Class
und findet dort eine Instanzmethode namens
new
.
Sie haben richtig gelesen: Der Algorithmus zur Namensauflösung für Methoden für die Klassen methode
C.new
findet schließlich die Instanz methode
Class.new
. Die Unterscheidung zwischen Instanzmethoden und Klassenmethoden ist zwar im objektorientierten Programmierparadigma nützlich, aber die Wahrheit ist, dass in Ruby – wo Klassen durch Objekte repräsentiert werden – der Unterschied eher künstlich ist. Jeder Methodenaufruf, egal ob Instanzmethode oder Klassenmethode, hat ein Zielobjekt und einen Methodennamen. Der Algorithmus zur Namensauflösung findet die passende Methodendefinition für dieses Objekt. Unser Objekt
C
ist eine Instanz der Klasse
Class
, daher können wir natürlich die Instanzmethoden von
Class
über
C
ansprechen. Zudem erbt
Class
die Instanzmethoden von
Module
,
Object
und
Kernel
, so dass diese geerbten Methoden ebenfalls als Methoden von
C
zur Verfügung stehen. Der einzige Grund dafür, dass wir sie als »Klassenmethoden« bezeichnen, ist der, dass unser Objekt
C
zufällig eine Klasse ist.
Unsere Klassenmethode
C.new
wird als Instanzmethode von
Class
gefunden. Wenn das nicht der Fall gewesen wäre, würde der Algorithmus wie für eine Instanzmethode weitermachen. Nach dem erfolglosen Durchsuchen von
Class
würden wir in Modulen schauen (von denen
Class
keine einbindet) und dann in der Superklasse
Module
. Als Nächstes würden die Module von
Module
durchsucht (es gibt keine) und schließlich die Superklasse
Object
von
Module
und dessen Modul
Kernel
.
Der am Anfang dieses Abschnitts erwähnte Spezialfall hat etwas mit der Tatsache zu tun, dass Klassenmethoden so wie Instanzmethoden vererbt werden. Lassen Sie uns eine Klassenmethode
Integer.parse
als Beispiel definieren:
def Integer.parse(text)
text.to_i
end
Da
Fixnum
eine Subklasse von
Integer
ist, können wir diese Methode auch mit folgendem Ausdruck aufrufen:
n = Fixnum.parse("1")
Aus der Beschreibung des Algorithmus zur Auflösung von Methodennamen wissen wir, dass Ruby erst in der Eigenklasse von
Fixnum
nach Singleton-Methoden suchen würde. Dann kämen die Instanzmethoden von
Class
,
Module
,
Object
und
Kernel
an die Reihe. Wo findet der Algorithmus also die Methode
parse
? Eine Klassenmethode von
Integer
ist einfach eine Singleton-Methode des Objekts
Integer
, was bedeutet, dass sie in der Eigenklasse von
Integer
definiert ist. Wo kommt nun diese Eigenklasse von
Integer
bei der Namensauflösung ins Spiel?
Klassenobjekte sind etwas Besonderes: Sie haben Superklassen. Die Eigenklassen von Klassenobjekten sind auch besonders: Sie haben ebenfalls Superklassen. Die Eigenklasse eines normalen Objekts steht für sich allein und hat keine Superklasse. Lassen Sie uns mit den Namen
Fixnum'
und
Integer'
die Eigenklassen von
Fixnum
und
Integer
bezeichnen. Die Superklasse von
Fixnum'
ist
Integer'
.
Mit diesem Sonderweg können wir nun den Algorithmus zur Auflösung von Methodennamen vollständig beschreiben und sagen, dass Ruby bei der Suche nach Singleton-Methoden in der Eigenklasse eines Objekts auch die Superklasse (und alle Vorfahren) der Eigenklasse durchsucht. Wenn also nach einer Klassenmethode von
Fixnum
gesucht wird, prüft Ruby zuerst die Singleton-Methoden von
Fixnum
,
Integer
,
Numeric
und
Object
und dann die Instanzmethoden von
Class
,
Module
,
Object
und
Kernel
.
7.9 Lookup von Konstanten
Wenn eine Konstante ohne qualifizierenden Namensraum referenziert wird, muss der Ruby-Interpreter die passende Definition der Konstante finden. Dazu nutzt er einen Algorithmus zur Namensauflösung — ganz so wie beim Finden von Methodendefinitionen. Allerdings werden Konstanten deutlich anders aufgelöst als Methoden.
Ruby versucht zuerst, eine Referenz auf eine Konstante im lexikalischen Gültigkeitsbereich der Referenz aufzulösen. Das bedeutet, dass es zunächst die Klasse oder das Modul prüft, in dem die Konstantenreferenz steht, um zu sehen, ob dort die Konstante definiert ist. Wenn nicht, prüft es die nächste umhüllende Klasse oder das umhüllende Modul. Das wird fortgesetzt, bis es keine umhüllenden Klassen oder Module mehr gibt. Beachten Sie, dass Konstanten auf oberster Ebene (»global«) nicht als Teil des lexikalischen
Weitere Kostenlose Bücher