Was ist die Beziehung zwischen der metaclass of Base und abgeleitete Klasse in Ruby?
-
22-09-2019 - |
Frage
In Ruby wir super
innerhalb Singleton-Methode aufrufen, um die entsprechenden Superklasse des Singleton-Methode, wie im folgenden Code dargestellt nutzen könnten.
class Base
def self.class_method
puts "Base class method"
end
end
class Derived < Base
def self.class_method
puts "Derived class method"
super
end
end
Derived.class_method
# Derived class method
# Base class method
Allerdings habe ich nicht ganz scheint, wie das Gespräch super
innerhalb Derived.class_method
Base.class_method
erreichen kann. Ich würde davon ausgehen, dass class_method
auf ihre Metaklasse definiert sind, bedeutet das, ihre metaclass Eltern / Kind-Beziehung hat? (Ich kann nicht ganz bestätigen, dass durch Experimente)
Update : ich diese Frage bin gefragt, weil ich sehe, erinnerte irgendwo es gibt eine Art von Beziehung bettwen Basis und abgeleiteten Klasse metaclass (aber ich kann es nicht finden nicht mehr). Darüber hinaus, wie eigentlich super
Werke wissen, ich möchte auch, um zu bestätigen, ob die beiden metaclasses völlig getrennt sind oder nicht.
Lösung
Es gibt vier Klassenobjekte im Spiel hier:
<Class>---class---><Class>
Base #Base
^ ^
| |
| |
super super
| |
| |
<Class> <Class>
Derived---class--->#Derived
Nomenklatur:
- <...> ist die Klasse von jedem Objekt.
- Der Name der Klasse in der zweiten Zeile ist.
- Wenn der Name beginnt mit #, es ist die Eigenklasse (aka Singletonklasse).
- Superpunkte zu einer Klasse der übergeordneten Klasse
- Klasse verweist auf die Klasse seiner Klasse.
Wenn Sie Derived.class_method nennen, folgt Ruby die „richtigen und dann nach oben“ Regel: Zuerst geht auf die Klasse des Objekts, dann folgt der Oberkette auf, zu stoppen, wenn die Methode gefunden wird:
- Der Empfänger des „class_method“ Anruf stammt. So folgt der Kette Recht auf Objekt abgeleitete Klasse, die ihre Eigenklasse ist (#Derived).
-
Abgeleitet nicht die Methode definieren, so Rubin die Kette auf der Kette # der übergeordneten Klasse abgeleitet folgt, die #Base ist.
- Das Verfahren ist dort zu finden, so Rubin die Nachricht an # Base.class_method entsendet
Sie glauben doch nicht, dass ich dieses Zeug aus der Spitze von meinem Kopf wusste, nicht wahr? Hier ist, wo mein Gehirn hat diese alle Meta Juju. Metaprogrammierung Ruby-
Teil 2. Wie eine "Eigenklasse" zu machen (auch bekannt als "Singletonklasse") kommen aus ihren Verstecken
class Object
def eigenclass
class << self
self
end
end
end
Diese Methode wird die Eigenklasse eines Objekts zurück. Nun, was Klassen? Das sind Objekte, auch.
p Derived.eigenclass # => #<Class:Derived>
p Derived.eigenclass.superclass # => #<Class:Base>
p Base.eigenclass # => #<Class:Base>
Hinweis: Oberhalb von ruby1.9 ist. Wenn unter Ruby 1.8 laufen, erhalten Sie eine Überraschung:
p Derived.eigenclass.superclass # => #<Class:Class>
Andere Tipps
Um zu klären und zu korrigieren, was ich in den Kommentaren in Bezug auf die Art und Weise schrieb Ruby-Häute / Exposes eigenclasses, hier ist die Situation:
Ruby 1.8:
(1) Die Object#class
Methode liefert immer die erste echte (nicht Eigenklasse oder iclass) geordnete Klasse der ist Klasse eines Objekts.
z
o = Object.new
class << o; end
o.class #=> returns Object, even though the _actual_ class is the eigenclass of o
Mit anderen Worten wird die Object#class
Methode nie eine Eigenklasse zurückkehren, geht es über sie
und stattdessen gibt die erste ‚echte‘ Klasse in der Vererbungshierarchie findet.
(2) Die Class#superclass
Methode hat zwei Fälle. Wenn der Empfänger nicht ein Eigenklasse ist dann kehrt er einfach die übergeordnete Klasse. Wenn jedoch der Empfänger is ein Eigenklasse dann diese Methode gibt die ist (das heißt nicht unbedingt real) Klasse des Empfängers.
# case where receiver is a normal class (i.e not an eigenclass)
Module.superclass #=> Object (behaves as expected)
# case where receiver is an eigenclass
class << Module; superclass; end #=> returns Class, this is NOT the superclass
Von oben Class#superclass
verhält sich wie bei einer normalen Klasse zu erwarten, sondern auch für die Eigenklasse Beispiel heißt es, die übergeordnete Klasse der Eigenklasse des Moduls ist Klasse, die nicht wahr ist. Aus diesem Diagramm http: //banisterfiend.wordpress. com / 2008/10/25 / the-secret-Leben-of-Singletons / wir wissen, dass die Eigenklasse von Object eigentlich, dass die übergeordneten Klasse der Eigenklasse des Moduls ist. Ich bin nicht sicher, warum Ruby 1.8 dieses seltsame Verhalten hat.
Ruby 1.9:
(1) Die Object#class
Methode verhält sich identisch zu der Version 1.8.
(2) Die Class#superclass
Methode nicht mehr zwei Fällen ist es jetzt behandelt eigenclasses die gleiche Art und Weise es normal, Klassen und kehrt die tatsächliche Super wie erwartet behandelt.
z
class << Module; superclass; end #=> #<Class:Object>
Dieses Diagramm erklärt die Beziehung: http: //banisterfiend.wordpress.com/2008/11/25/a-complete-ruby-class-diagram/
Auch sind hier einige andere Beiträge, die mehr die Feinheiten der eigenclasses erklären: http://www.klankboomklang.com/2007/10/05/the -metaclass /
http://www.klankboomklang.com/2007/ 21.09 / the-Singleton-Klasse /
Und hier ist ein ziemlich hart geht, die mehr erklärt, als Sie wahrscheinlich würde gerne wissen: http://banisterfiend.wordpress.com/2008 10 / / 25 / the-secret-Leben-of-Singletons /