InhaltsverzeichnisKlicke auf den Link, um zur gewünschten Stelle zu navigieren
Dieser Inhalt wurde automatisch aus dem Ukrainischen übersetzt.
Im Ruby-Modul können Sie Code organisieren, aber manchmal muss eine Methode sowohl für Instanzen des Moduls als auch direkt aus dem Modul (wie eine Funktion) zugänglich sein. Dafür wird module_function verwendet.
Wie module_function funktioniert
- macht die Methode privat für Instanzen des Moduls (lesen Sie hier über private).
- fügt auch eine "Modulkopie" der Methode hinzu, die ohne Erstellung eines Objekts aufgerufen werden kann.
module MathHelper
def square(x)
x * x
end
module_function :square
end
Jetzt kann die Methode direkt über das Modul aufgerufen werden:
MathHelper.square(5) # => 25
Oder sie kann innerhalb anderer Methoden des Moduls verwendet werden (wie privat):
module MathHelper
def cube(x)
square(x) * x
end
module_function :cube
end
MathHelper.cube(3) # => 27
Besonderheiten
Privat für Instanzen des Moduls:
include MathHelper square(5) # => NoMethodError (weil square privat geworden ist)
Eignet sich für Utilities
module_function wird häufig in "statischen Utilities" verwendet, um kein Modulobjekt zu erstellen, um Funktionen aufzurufen.
Zusammengefasst:
- module_function macht die Methode gleichzeitig:
- Privat für Instanzen (durch include)
- Als Funktion verfügbar über das Modul
MathHelper.square(5) # funktioniert include MathHelper square(5) # Fehler
Dies ist praktisch für Module, die eine Sammlung von Utilities haben, wie in den Standardbibliotheken von Ruby (Math, Enumerable zum Beispiel).
Aber wenn Sie auf den Punkt achten - privat für Instanzen (durch include), könnten Sie fragen, was ist mit extend und prepend (über diese Methoden habe ich hier geschrieben)?
- Die Modulmethode wird privat für Instanzen und über das Modul verfügbar.
- Der Aufruf über include funktioniert nicht direkt (die Methode ist privat).
- Der Aufruf über extend funktioniert als Klassenmethode.
- Der Aufruf über prepend funktioniert nicht auf dem Objekt (die Methode ist privat).
Immer noch schwer zu verstehen? Lassen Sie uns das genauer betrachten:
module_function macht zwei Dinge gleichzeitig:
-
Privat für Instanzen
- Wenn Sie das Modul einfügen (include) oder prepend, wird die Methode privat für alle Objekte, das heißt, Sie können sie nicht einfach so aufrufen: obj.method - es wird ein Fehler sein.
- Ruby macht das, damit Sie diese Methode nicht versehentlich auf einer Instanz aufrufen können.
-
Über das Modul verfügbar
- Ruby erstellt eine Kopie der Methode auf Modulebene.
- Deshalb kann man aufrufen: ModuleName.method - das funktioniert wie eine "statische Funktion".
Ein einfaches Beispiel:
module Utils
def greet
"Hallo"
end
module_function :greet
end
# Über das Modul kann man
Utils.greet # => "Hallo"
# Über include — kann man nicht, weil privat
include Utils
greet # => Fehler NoMethodError
- Warum funktioniert extend? extend fügt die Methoden des Moduls in die Singleton-Klasse der Klasse oder des Objekts ein. Dort wird die Methode über die Klasse/das Objekt aufgerufen, nicht über die Instanz, das heißt, es funktioniert.
- Warum funktioniert prepend nicht? prepend fügt die Methode in die Vererbungskette ein, aber die ursprüngliche Methode bleibt privat -> das Objekt kann sie nicht direkt aufrufen.
Dieser Beitrag hat noch keine Ergänzungen vom Autor.