Die Programmiersprache Ruby (German Edition)
doubler.binding.eval("n=3") in Ruby 1.9
puts doubler.call([1,2,3]) # Dies gibt jetzt 3,6,9 aus!
Zur Vereinfachung erlaubt die Methode
eval
Ihnen, ein
Proc
-Objekt direkt zu übergeben, anstatt das
Binding
-Objekt der
Proc
zu übergeben. Deshalb könnten wir den obigen
eval
-Aufruf wie folgt ersetzen:
eval("n=3", doubler)
Bindungen sind nicht nur ein Feature von Closures. Die Methode
Kernel.binding
gibt an jedem Punkt, an dem Sie sie gerade aufrufen, ein
Binding
-Objekt zurück, das die zurzeit wirksamen Bindungen repräsentiert.
6.7 Method-Objekte
Rubys Methoden und Blöcke sind ausführbare Sprachkonstrukte, aber keine Objekte. Procs und Lambdas sind Objektversionen von Blöcken; sie können sowohl ausgeführt als auch als Daten manipuliert werden. Ruby besitzt leistungsfähige Metaprogrammierungsfähigkeiten (bzw. Reflexionsfähigkeiten ), und Methoden können eigentlich als Instanzen der Klasse
Method
dargestellt werden. (Metaprogrammierung wird in Kapitel 8 dargestellt, aber
Method
-Objekte werden hier vorgestellt.) Sie sollten beachten, dass der Aufruf einer Methode durch ein
Method
-Objekt effizienter ist als der direkte Aufruf der Methode.
Method
-Objekte werden normalerweise nicht so häufig genutzt wie Lambdas und Procs.
Die Klasse
Object
definiert eine Methode namens
method
. Übergeben Sie ihr einen Methodennamen als String oder als Symbol, und sie gibt ein
Method
-Objekt zurück, das die genannte Methode des Empfängers repräsentiert (oder löst einen
NameError
aus, wenn eine solche Methode nicht existiert), zum Beispiel:
m = 0.method(:succ) # Ein Method-Objekt, das die Methoder succ der Fixnum 0 darstellt
In Ruby 1.9 können Sie
public_method
verwenden, um ein
Method
-Objekt zurückzugeben. Das funktioniert wie
method
, ignoriert aber Protected- und Private-Methoden (siehe „7.2 Sichtbarkeit von Methoden: public, protected, private“ ).
Die Klasse
Method
ist keine Unterklasse von
Proc
, verhält sich aber recht ähnlich.
Method
-Objekte werden mit der Methode
call
(oder mit dem
[]
-Operator) aufgerufen, genau wie
Proc
-Objekte. Und
Method
definiert eine
arity
-Methode, die der
arity
-Methode von
Proc
entspricht. So rufen Sie die Methode
m
auf:
puts m.call # Das Gleiche wie puts 0.succ. Oder verwenden Sie puts m[].
Der Aufruf einer Methode über ein
Method
-Objekt ändert weder die Aufrufsemantik noch die Bedeutung von Steuerungsablaufanweisungen wie
return
und
break
. Die Methode
call
eines
Method
-Objekts verwendet Methodenaufrufsemantik, keine
yield
-Semantik. Daher verhalten sich
Method
-Objekte eher wie Lambdas als wie Procs.
Method
-Objekte funktionieren recht ähnlich wie
Proc
-Objekte und können normalerweise an ihrer Stelle verwendet werden. Wenn eine echte
Proc
benötigt wird, können Sie
Method.to_proc
verwenden, um eine
Method
in eine
Proc
zu konvertieren. Das ist der Grund, warum
Method
-Objekte mit einem Und als Präfix anstelle eines Blocks an eine Methode übergeben werden können, zum Beispiel:
def square(x); x*x; end
puts (1..10).map(&method(:square))
----
Methoden mit Procs definieren
Wir können nicht nur ein
Method
-Objekt erhalten, das eine Methode repräsentiert, und dieses in eine
Proc
konvertieren, sondern auch in die umgekehrte Richtung gehen. Die Methode
define_method
(von
Module
) erwartet ein
Symbol
als Argument und erzeugt eine Methode dieses Namens, die den verknüpften Block als Methodenrumpf verwendet. Statt eines Blocks können Sie auch ein
Proc
- oder
Method
-Objekt als zweites Argument übergeben.
----
Ein wichtiger Unterschied zwischen
Method
-Objekten und
Proc
-Objekten besteht darin, dass
Method
-Objekte keine Closures sind. Rubys Methoden sollen vollkommen in sich abgeschlossen sein und haben niemals Zugriff auf lokale Variablen außerhalb ihres eigenen Gültigkeitsbereichs. Die einzige Bindung, die ein
Method
-Objekt enthält, ist daher die Bindung an
self
– das Objekt, für das die Methode aufgerufen wird.
In Ruby 1.9 definiert die Klasse
Method
drei Methoden, die in 1.8 nicht verfügbar sind:
name
gibt den Namen der Methode als String zurück;
owner
liefert die Klasse zurück, in der die Methode definiert wurde;
receiver
schließlich gibt das Objekt zurück, an das die Methode gebunden ist. Für jedes Methodenobjekt
m
muss
m.receiver.class
identisch mit oder eine Unterklasse von
m.owner
sein.
6.7.1 UnboundMethod-Objekte
Zusätzlich zur Klasse
Method
definiert Ruby auch eine Klasse namens
UnboundMethod
. Wie der Name vermuten lässt, stellt
Weitere Kostenlose Bücher