Alle Originalinhalte werden auf Ukrainisch erstellt. Noch nicht alle Inhalte wurden übersetzt. Einige Beiträge sind möglicherweise nur auf Ukrainisch verfügbar.Mehr erfahren

Include, Extend, Prepend in Ruby: wie sie funktionieren und wo der Unterschied liegt

Beitrags-Cover: Include, Extend, Prepend in Ruby: wie sie funktionieren und wo der Unterschied liegt
Dieser Inhalt wurde automatisch aus dem Ukrainischen übersetzt.
In Ruby werden Module zur Wiederverwendung von Code verwendet. Die Methode zum Hinzufügen eines Moduls beeinflusst wann und wie Methoden aus dem Modul verfügbar werden.

include - fügt Methoden als Instanzmethoden hinzu

  • Modulmethoden werden für alle Objekte der Klasse verfügbar.
  • Wird verwendet, wenn man möchte, dass die Methoden in Instanzen der Klasse vorhanden sind.
module Greetings
  def hello
    "Hi!"
  end
end

class User
  include Greetings
end

u = User.new
u.hello # => "Hi!"
Modulmethoden erscheinen in der Vererbungskette der Klasse (ancestors) nach der Klasse selbst, das heißt, sie können in der Klasse überschrieben werden. Aber lassen Sie uns das genauer betrachten. In Ruby hat jede Klasse eine Vererbungskette (ancestors) - die Reihenfolge, in der Ruby nach Methoden sucht, wenn sie auf einem Objekt aufgerufen werden.
module Greetings
  def hello
    "Hi from module"
  end
end

class User
  include Greetings

  def hello
    "Hi from class"
  end
end

p User.ancestors
# => [User, Greetings, Object, Kernel, BasicObject]
Wenn Sie include Greetings verwenden, fügt Ruby das Modul nach der Klasse in die Vererbungskette ein. Oder einfacher gesagt - über der Klasse.
Das bedeutet, dass Klassenmethoden Modulmethoden überschreiben, wenn sie denselben Namen haben.
u = User.new
u.hello # => "Hi from class"
Ruby sucht zuerst nach der Methode in der Klasse selbst (User). Wenn sie nicht gefunden wird, überprüft sie die Module in der Kette (Greetings), dann die Vorfahren (Object, Kernel).

extend - fügt Methoden als Klassenmethoden hinzu

  • Modulmethoden werden direkt auf der Klasse verfügbar, nicht auf Instanzen.
  • Praktisch zum Hinzufügen von "Klassenmethoden" ohne explizites self.method.
module Tools
  def info
    "Class method!"
  end
end

class User
  extend Tools
end

User.info # => "Class method!"
User.new.info # => NoMethodError
Tatsächlich fügt Ruby Methoden zur singleton class des Objekts hinzu (die Klasse selbst ist ein Objekt).

prepend - fügt Methoden vor der Klasse in der Vererbungskette hinzu

  • Modulmethoden erscheinen vor der Klasse in der Vererbungskette.
  • Das bedeutet, dass Modulmethoden Klassenmethoden überschreiben können.
module Greetings
  def hello
    "Hello from module"
  end
end

class User
  prepend Greetings

  def hello
    "Hello from class"
  end
end

p User.ancestors
# => [Greetings, User, Object, Kernel, BasicObject]
Der entscheidende Punkt: Greetings steht vor der Klasse User.
Ruby sucht Methoden in der Reihenfolge, die ancestors zeigt.
Deshalb, wenn Sie u.hello aufrufen, sieht Ruby zuerst die Methode im Modul Greetings und dann in der Klasse User.
u = User.new
u.hello # => "Hello from module"
Verwendung von super im Modul
Wenn im Modul super aufgerufen wird, geht Ruby weiter in der Vererbungskette und führt die Methode der Klasse aus:
module Greetings
  def hello
    super + " and module"
  end
end

class User
  prepend Greetings

  def hello
    "Hello from class"
  end
end

u = User.new
u.hello # => "Hello from class and module"
Warum ist das so?
  1. Ruby ruft hello im Modul Greetings auf (da es das erste in ancestors ist).
  2. Dort gibt es super. Ruby sucht die nächste Methode in der Vererbungskette, also in der Klasse User.
  3. Die Klassenmethode gibt "Hello from class" zurück, dann wird " and module" hinzugefügt.

Zusammenfassend

include -> Modulmethoden werden zu Instanzmethoden der Klasse, das Modul steht nach der Klasse in der Vererbungskette.
extend -> Modulmethoden werden zu Methoden der Klasse oder eines bestimmten Objekts (singleton class).
prepend -> Modulmethoden werden zu Instanzmethoden, aber vor der Klasse in der Vererbungskette, das heißt, sie haben Vorrang vor Klassenmethoden.

Dieser Beitrag hat noch keine Ergänzungen vom Autor.

Ganzzahlige Division in Ruby: Warum 6 / 4 gleich 1 ist
28. Okt, 14:10 Uhr

Ganzzahlige Division in Ruby: Warum 6 / 4 gleich 1 ist

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
28. Okt, 14:42 Uhr

Wie funktioniert &:to_s in Ruby und was ist Symbol#to_proc

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Was sind Proc und Lambda in Ruby?
28. Okt, 15:57 Uhr

Was sind Proc und Lambda in Ruby?

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Was passiert, wenn man [1, 2, 3].map(&Person) aufruft?
29. Okt, 17:54 Uhr

Was passiert, wenn man [1, 2, 3].map(&Person) aufruft?

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Singleton-Klasse (Eigenklasse) in Ruby: was ist das und wozu wird sie benötigt
29. Okt, 18:29 Uhr

Singleton-Klasse (Eigenklasse) in Ruby: was ist das und wozu wird sie benötigt

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
==, gleich?, eql?, === in Ruby: was sie überprüfen und wann man sie verwenden sollte
29. Okt, 20:47 Uhr

==, gleich?, eql?, === in Ruby: was sie überprüfen und wann man sie verwenden sollte

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
module_function in Ruby: wenn die Methoden eines Moduls sowohl als Modulmethoden als auch als Funktionen verfügbar sind
29. Okt, 21:53 Uhr

module_function in Ruby: wenn die Methoden eines Moduls sowohl als Modulmethoden als auch als Funktionen verfügbar sind

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Was ist Memoization in Ruby?
30. Okt, 10:17 Uhr

Was ist Memoization in Ruby?

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
is_a?, kind_of?, instance_of? — wie prüft Ruby den Typ eines Objekts?
30. Okt, 19:55 Uhr

is_a?, kind_of?, instance_of? — wie prüft Ruby den Typ eines Objekts?

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
&& vs and — der Unterschied in Ruby, der Ihren Code brechen kann
30. Okt, 20:23 Uhr

&& vs and — der Unterschied in Ruby, der Ihren Code brechen kann

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Variablen in Ruby: @, @@ und Klasseninstanzvariablen
30. Okt, 20:54 Uhr

Variablen in Ruby: @, @@ und Klasseninstanzvariablen

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska
Der Unterschied zwischen blank?, present?, empty? und nil? in Ruby
30. Okt, 21:06 Uhr

Der Unterschied zwischen blank?, present?, empty? und nil? in Ruby

Нотатки про Ruby та RoR
Нотатки про Ruby та RoR@kovbaska