Vererbung der Ruby-Klasse: Was ist "<<" (doppelt so viel wie)?


74
class << Awesomeness

Wofür ist das <<? Ich habe gesucht, aber die Ergebnisse sagen nur etwas über die Verkettung von Zeichenfolgen aus ...

Antworten:


134

Während es wahr ist, dass dies class << somethingdie Syntax für eine Singleton-Klasse ist, wie jemand anderes sagte, wird sie am häufigsten verwendet, um Klassenmethoden innerhalb einer Klassendefinition zu definieren. Diese beiden Verwendungen sind jedoch konsistent. Hier ist wie.

Mit Ruby können Sie einer bestimmten Instanz Methoden hinzufügen, indem Sie Folgendes tun:

class << someinstance
  def foo
    "Hello."
  end
end

Dies fügt einer fooInstanz eine Methode hinzu, nicht ihrer Klasse, sondern dieser einen bestimmten Instanz. (Tatsächlich wird foo zur "Singleton-Klasse" der Instanz hinzugefügt, aber das ist mehr oder weniger eine Implementierungs-Eigenart.) Nachdem der obige Code ausgeführt wurde, können Sie die Methode foo an eine Instanz senden:

someinstance.foo   => "Hello."

Sie können foo jedoch nicht an andere Instanzen derselben Klasse senden. Dafür <<ist nominell. Diese Funktion wird jedoch häufiger für syntaktische Gymnastik wie diese verwendet:

class Thing
  def do_something
  end

  class << self
    def foo
      puts "I am #{self}"
    end
  end
end

Was ist, wenn dieser Code - diese Klassendefinition - ausgeführt wird self? Es ist die Klasse Thing. Dies bedeutet, class << selfdass Sie der Klasse Thing die folgenden Methoden hinzufügen. Das heißt, foo ist eine Klassenmethode. Nachdem der obige Vorgang abgeschlossen ist, können Sie Folgendes tun:

t = Thing.new
t.do_something  => does something
t.class.foo     => "I am Thing"
t.foo           => NoMethodError: undefined method `foo'

Und wenn Sie darüber nachdenken, was <<gerade passiert, macht alles Sinn. Es ist eine Möglichkeit, an eine bestimmte Instanz anzuhängen, und im allgemeinen Fall ist die angehängte Instanz eine Klasse, sodass die Methoden innerhalb des Blocks zu Klassenmethoden werden.

Kurz gesagt, es ist eine knappe Möglichkeit, Klassenmethoden innerhalb eines Klassendefinitionsblocks zu erstellen. Ein anderer Weg wäre, dies zu tun:

class Thing
  def self.foo
    # ...
  end
end

Gleiche Sache. Ihr Beispiel ist eigentlich ein Syntaxfehler. Wenn Sie jedoch <<wissen, wie Instanzen und das Schlüsselwort class verwendet werden, wissen Sie, wie Sie ihn korrigieren können.


1
Interessant! Ist eine solche Methode in der täglichen Programmierung nützlich?
Voldemort

5
@Omega: Ja, Sie würden dies zum Beispiel sehen, wenn Sie mehr als eine Methode haben, mit der Sie eine Klassenmethode erstellen möchten, und Sie nicht möchten, dass allen "self" vorangestellt wird. Sie können sie einfach alle in diesen Block legen und sich keine Sorgen machen.
Solidcell

großartige Arbeit - diese entmystifizierten anderen Antworten, auf die ich gestoßen bin.
Larry

Das letzte bisschen hat alles zum Klicken gebracht. Beachten Sie auch, dass dies class << selfin dem Sinne funktioniert, dass es sich zwar Thingum eine Klasse handelt, aber auch nur um eine Instanz ihrer Oberklasse. Klassen und Instanzen haben also nichts Besonderes. Jede Klasse in Ruby ist eine Instanz ihrer Oberklasse (außer BasicObject).
Ahnbizcad

Vielen Dank für die Erklärung, es wurde sehr gut erklärt.
Pixel 67


20

Wenn Sie eine Vererbung wünschen (basierend auf Ihrem Fragentitel), möchten Sie eine einzelne <:

class Awesome < ParentAwesomeness

Der von Ihnen angegebene Code ist kein gültiger Ruby:

class Awesomeness
end

class Awesome << Awesomeness
end

SyntaxError: (irb):3: syntax error, unexpected tLSHFT, expecting '<' or ';' or '\n'

Gut zu wissen. Dieses Faktoid ist bei der Suche schwer zu finden.
Ahnbizcad

lustig, wie wenige Leute sich den Titel angesehen haben. Die anderen Erklärungen sind großartig, haben aber irgendwie verpasst, wonach der Fragesteller gesucht hat.
ObjectNameDisplay
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.