Ruby-Programmierung: Module
Zurück zum Inhaltsverzeichnis.
Unter Modulen ist es möglich Rubycode zu einer logischen Einheit zusammenzufassen, das kann sich je nach Anwendungszweck auf einzelne Methoden, Konstanten oder ganze Klassen beziehen. Dadurch wird es möglich diese Bündel zusammen zu verwenden und Konflikte zwischen Namen zu verhindern.
Module
BearbeitenModule werden wie Klassen definiert und folgen den gleichen Namenskonventionen. Die parallelen zwischen Klassen und Modulen in Bezug auf Kapselung des Codes geht noch weiter, so dass das folgende Skript die gleiche Funktionalität auch mit class Example
haben würde. Bei der Verwendung von Modulen erreichen Sie nichts, was nicht auch durch Verwendung von Klassen möglich wäre. Die Verwendung eines Moduls sollten Sie immer dann einer Klasse vorziehen, wenn die Bildung einer Instanz keinen Sinn hat oder mehrere Klassen zusammengehören.
module Example
class Hello
def self.world
puts "Hello World!"
end
end
end
Example::Hello.world
Modulfunktionen
BearbeitenNeben der Möglichkeit Module in Objekte einzufügen, was im Kapitel Vererbung besprochen wird, ist es nur möglich die Modulfunktionen eines Moduls zu benutzen, da Instanzmethoden eine Objektinstanz voraussetzen. Sie unterscheiden sich genauso wie Klassen- und Instanzmethoden der Objekte aus dem vorherigen Kapitel.
Das folgende Listing definiert mehrere Methoden für das Modul. Der Zugriff auf alle Methoden erfolgt gleich mit Example::METHOD
.
module Example
def one
puts "module_function"
end
module_function :one
def Example::two
puts "Example::two"
end
def self.three
puts "self.three"
end
end
Wenn keine Namenskonflikte vorliegen, kann man ein Module in den aktuellen Namensraum einfügen durch die Verwendung include
. Mit dem oben definierten Module also so:
include Example
one
Wenn vorher eine Methode exisitert, die mit dem include
in Konflikt steht, wird die Methode nicht überschrieben und die Modulmethode ist weiterhin nur über Example::one
aufrufbar.
Namensraumoperator
BearbeitenDer Operator ::
beschreibt der Maschine, wie sie einen bestimmten Namen suchen muss. Im obigen Beispiel mit Example::one
wird also bestimmt, dass es zuerst nötig ist, eine Klasse oder ein Modul mit dem Namen Example
zu suchen und dann in diesem Modul die Methode mit dem Namen one
. Dabei werden verwendete Aufrufe innerhalb dieser Methoden dann von innen nach außen gesucht, was unter bestimmten Umständen zu Problem führen kann.
module Example
def self.random_string
String.new("abc123")
end
class String
end
end
puts Example::random_string
Das obige Skript definiert ein Modul, das eine Methode und eine Klasse enthält. Die Methode soll einen String anlegen und wird aufgerufen. Das Problem daran ist, dass beim Aufruf von random_string
nun in den Namensräumen von innen nach außen nach einer Klasse String
gesucht wird. Der Konstruktor der Klasse Example::String
erhält jedoch keine Parameter, sodass das obige Skript mit einem Fehler abbricht. Es ist möglich, explizit die Stringklasse des globalen Namensraums zu verwenden durch das Präfix ::
. Das Skript beendet erwartungsgemäß durch Ändern der entsprechenden Zeile zu ::String.new("abc123")
.