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.

War es hilfreich?

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 /

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top