Die Programmiersprache Ruby (German Edition)
definieren möchten, verwenden Sie
define_method
. Diese Instanzmethode von
Module
nimmt den Namen der neuen Methode (als
Symbol
) als erstes Argument entgegen. Der Rumpf der Methode wird entweder durch ein
Method
-Objekt bereitgestellt, das als zweites Argument übergeben wird, oder aber durch einen Block. Es ist wichtig, zu verstehen, dass die Methode
define_method
privat ist. Sie müssen sich innerhalb der Klasse oder des Moduls befinden, wo Sie sie verwenden möchten, um sie aufzurufen:
# Eine Instanzmethode m mit Rumpf b zur Klasse c hinzufügen
def add_method(c, m, &b)
c.class_eval {
define_method(m, &b)
}
end
add_method(String, :greet) { "Hallo, " + self }
"Welt".greet # => "Hallo, Welt"
Um mit
define_method
eine Klassenmethode (oder irgendeine Singleton-Methode) zu definieren, rufen Sie
define_method
für die Eigenclass auf:
def add_class_method(c, m, &b)
eigenclass = class << c; self; end
eigenclass.class_eval {
define_method(m, &b)
}
end
add_class_method(String, :greet) {|name| "Hallo, " + name }
String.greet("Welt") # => "Hallo, Welt"
----
Attributakzessormethoden definieren
Die Methoden
attr_reader
und
attr_accessor
(siehe „7.1.5 Akzessoren und Attribute“ ) definieren ebenfalls neue Methoden für eine Klasse. Genau wie
define_method
sind sie private Methoden von
Module
und können im Hinblick auf
define_method
leicht implementiert werden. Diese Methodenerzeugungsmethoden sind ein exzellentes Beispiel für die Nützlichkeit von
define_method
. Beachten Sie, dass diese Methoden für den Gebrauch innerhalb einer Klassendefinition gedacht sind und daher nicht durch die Tatsache beeinträchtigt werden, dass
define_method
privat ist.
----
In Ruby 1.9 können Sie einfach
define_singleton_method
verwenden, eine Methode von
Object
:
String.define_singleton_method(:greet) {|name| "Hallo, " + name }
Ein Mangel der Methode
define_method
besteht darin, dass sie Ihnen nicht erlaubt, einen Methodenrumpf anzugeben, der einen Block erwartet. Wenn Sie dynamisch eine Methode erstellen müssen, die einen Block akzeptiert, müssen Sie die Anweisung
def
mit
class_eval
verwenden. Und wenn die Methode, die Sie erstellen, hinreichend dynamisch ist, sind Sie möglicherweise nicht in der Lage, einen Block an
class_eval
zu übergeben, sondern müssen die Methodendefinition stattdessen als auszuwertenden String angeben. Weiter unten in diesem Kapitel werden wir Beispiele dafür sehen.
Um ein Synonym oder einen Alias für eine existierende Methode zu erstellen, können Sie normalerweise die Anweisung
alias
verwenden:
alias plus + # "plus" zum Synonym für den operator + machen
Wenn Sie allerdings dynamisch programmieren, müssen Sie stattdessen manchmal
alias_method
verwenden. Genau wie
define_method
ist auch
alias_method
eine private Methode von
Module
. Als Methode kann sie zwei beliebige Ausdrücke als Argumente annehmen, anstatt zwei fest einprogrammierte Bezeichner in Ihrem Quellcode zu verlangen. (Als Methode benötigt sie zudem ein Komma zwischen ihren Argumenten.)
alias_method
wird oft zum Alias-Verkettung bestehender Methoden verwendet. Es folgt ein einfaches Beispiel; weiter unten in diesem Kapitel werden Sie noch mehr sehen:
# Einen Alias für die Methode m in Klasse (oder Modul) c erzeugen
def backup(c, m, prefix="original")
n = :"#{prefix}_#{m}" # Den Alias berechnen
c.class_eval { # Weil alias_method privat ist
alias_method n, m # n zum Alias für m machen
}
end
backup(String, :reverse)
"Test".original_reverse # => "tseT"
Wie wir in „6.1.5 Methodendefinitionen aufheben“ erfahren haben, können Sie die Anweisung
undef
verwenden, um die Definition einer Methode aufzuheben. Das funktioniert nur, wenn Sie den Namen einer Methode als fest einprogrammierten Bezeichner in Ihrem Programm ausdrücken können. Wenn Sie dynamisch eine Methode löschen müssen, deren Name durch Ihr Programm berechnet wurde, dann haben Sie zwei Möglichkeiten:
remove_method
oder
undef_method
. Beide sind private Methoden von
Module
.
remove_method
entfernt die Definition der Methode aus der aktuellen Klasse. Wenn es eine Version gibt, die durch eine Oberklasse definiert wird, dann wird diese Version nun vererbt. Die Methode
undef_method
ist strenger: Sie verhindert jeglichen Aufruf der angegebenen Methode durch eine Instanz der Klasse, selbst wenn es eine ererbte Version dieser Methode gibt.
Wenn Sie eine Klasse definieren und jegliche dynamische Manipulation derselben verhindern möchten, rufen Sie einfach die
Weitere Kostenlose Bücher