Frage
Wie kommt es, dass Ruby eine Klasse Zugriffsmethoden außerhalb der Klasse erlaubt implizit?
Beispiel:
class Candy
def land
homer
end
end
def homer
puts "Hello"
end
Candy.new.land #Outputs Hello
Lösung
Die Definition der „homer“ Methode ist das Hinzufügen des Verfahrens zum Objektklasse. Es ist nicht eine freie Funktion definiert wird.
Klasse Süßigkeit erbt implizit von Object, und so hat Zugriff auf die Methoden in Object. Wenn Sie „homer“ im „Land“ -Methode aufrufen, kann das Verfahren Auflösung keine Definition in der aktuellen Klasse finden, geht in die Superklasse, findet die Methode, die Sie hinzugefügt haben, Objekt, und es nennt.
Andere Tipps
Ein einfacher Weg, um herauszufinden, was passiert,
-
Welche Klassen / Module gesucht werden Methoden bei Candy Objekten zu lösen?
p Candy.ancestors # => [Candy, Object, Kernel]
-
Hat Süßigkeit haben Methode namens homer?
p Candy.instance_methods (false) .grep ( "homer") # => []
p Candy.private_instance_methods (false) .grep ( "homer") # => []
-
OK Süßigkeit hat keine Methode namens 'homer'.
-
Was in der Lookup-Kette als nächstes (siehe 1) => "Objekt"
-
Hat Objekt hat eine Methode namens "homer"? p Object.instance_methods (false) .grep ( "homer") # => []
p Object.private_instance_methods (false) .grep ( "homer") # => [ "homer"]
Candy hat in seiner Lookup-Kette Objekt, das wiederum eine private Instanz-Methode "homer" hat so Methode Auflösung gelingt
Die def-Anweisung definiert immer die Methode in der Klasse von was auch immer Selbst an der Stelle der Definition ist
-
Was ist self kurz vor homer definiert ist?
p Selbst # => Haupt def homer puts „Hallo“ Ende
-
Also, was ist seine Art?
p self.class # => Objekt
Weswegen homer landet auf Object
Technisch ist die Definition der homer
Methode tatsächlich auf dem Kernel
-Modul, das in Object
gemischt wird, nicht direkt auf Object
. Also, wenn homer
nicht eine lokale Variable oder eine Instanzmethode auf Candy
definiert ist, wird die Ruby-Methode Vererbungskette durch Object
verfolgt und dann auf die Misch in Kernel
Modul und dann wird dieser Code ausgeführt.
Edit: Sorry, ich weiß nicht, warum ich gedacht werden. Es scheint, dass die Methode wirklich lebt Object
. Nicht sicher, dass es zu viel von einem Unterschied in der Praxis macht, aber ich soll die Dinge bestätigt habe vor der Veröffentlichung.
Ruby hat keine freischwebenden Funktionen. Jede Methode gehört zu einem Objekt. Methoden, die Sie auf der obersten Ebene def
sind eigentlich immer Instanzmethoden der Klasse Object
. Weil alles, was ein Object
auf einer bestimmten Ebene ist, haben alle Objekte Zugriff auf Object
Instanzmethoden.