Die Programmiersprache Ruby (German Edition)
zusätzliche Möglichkeit, ein
Proc
-Objekt aufzurufen; als Alternative zu eckigen Klammern können Sie runde Klammern mit einem Punkt davor verwenden:
z = f.(x,y)
.()
sieht aus wie ein Methodenaufruf, in dem der Methodenname fehlt. Es ist kein Operator, der definiert werden kann, sondern ein Syntaxkürzel für den Aufruf der Methode
call
.
6.5.3 Die Stelligkeit einer Proc
Die Stelligkeit (englisch arity ) einer Proc oder eines Lambda ist die Anzahl von Argumenten, die sie erwarten. (Das Wort arity ist aus dem Suffix »ary« von unary, binary, ternary usw. abgeleitet.)
Proc
-Objekte besitzen eine
arity
-Methode, die die Anzahl der erwarteten Argumente zurückliefert, zum Beispiel
lambda{||}.arity # => 0. Keine Argumente erwartet
lambda{|x| x}.arity # => 1. Ein Argument erwartet
lambda{|x,y| x+y}.arity # => 2. Zwei Argumente erwartet
Die Stelligkeit wird komplizierter, wenn eine Proc in einem letzten Argument mit dem Präfix
*
eine beliebige Anzahl von Argumenten akzeptiert. Wenn eine
Proc
optionale Argumente erlaubt, gibt die Methode
arity
eine negative Zahl in der Form
-n-1
zurück. Ein Rückgabewert in dieser Form weist darauf hin, dass die
Proc n
Argumente benötigt, aber optional auch zusätzliche Argumente annehmen kann.
-n-1
wird als Einerkomplement von
n
bezeichnet, das Sie mit dem Operator
~
invertieren können. Wenn
arity
also eine negative Zahl
m
zurückgibt, dann liefert
~m
(oder
-m-1
) Ihnen die Anzahl der benötigten Argumente:
lambda {|*args|}.arity # => −1. ~-1 = -(-1)-1 = 0 Argumente benötigt
lambda {|first, *rest|}.arity # => −2. ~-2 = -(-2)-1 = 1 Argument benötigt
Die Methode
arity
weist eine letzte Besonderheit auf. In Ruby 1.8 kann eine ohne jegliche Argumente (das heißt ohne
||
-Zeichen) deklarierte
Proc
mit beliebig vielen Argumenten aufgerufen werden (und diese Argumente werden ignoriert). Die Methode
arity
gibt
−1
zurück, um anzuzeigen, dass keine Argumente benötigt werden. Dies hat sich in Ruby 1.9 geändert: Eine
Proc
, die auf diese Weise deklariert wird, hat die Stelligkeit
0
. Wenn sie ein Lambda ist, ist es ein Fehler, sie überhaupt mit Argumenten aufzurufen:
puts lambda {}.arity # −1 in Ruby 1.8; 0 in Ruby 1.9
6.5.4 Proc-Gleichheit
Die Klasse
Proc
definiert eine
==
-Methode, um zu ermitteln, ob zwei
Proc
-Objekte gleich sind. Es ist jedoch wichtig zu verstehen, dass derselbe Quellcode allein zwei Procs oder Lambdas noch nicht gleich macht:
lambda {|x| x*x } == lambda {|x| x*x } # => false
Die Methode
==
liefert nur dann
true
zurück, wenn die eine
Proc
ein Klon oder Duplikat der anderen ist:
p = lambda {|x| x*x }
q = p.dup
p == q # => true: Die beiden Procs sind gleich.
p.object_id == q.object_id # => false: Sie sind nicht dasselbe Objekt.
6.5.5 Wie Lambdas sich von Procs unterscheiden
Eine Proc ist die Objektform eines Blocks, und sie verhält sich wie ein Block. Ein Lambda besitzt ein leicht verändertes Verhalten und verhält sich eher wie eine Methode als wie ein Block. Der Aufruf einer Proc entspricht dem Aufruf eines Blocks, während der Aufruf eines Lambda dem Aufruf einer Methode entspricht. In Ruby 1.9 können Sie mithilfe der Instanzmethode
lambda?
herausfinden, ob ein
Proc
-Objekt eine Proc oder ein Lambda ist. Dieses Prädikat liefert für Lambdas
true
und für Procs
false
zurück.
6.5.5.1 Return in Blöcken, Procs und Lambdas
Wie in Kapitel 5 gezeigt, kehrt die Anweisung
return
selbst dann aus der lexikalisch umgebenden Methode zurück, wenn die Anweisung in einem Block enthalten ist. Die
return
-Anweisung in einem Block kehrt nicht nur aus dem Block zum aufrufenden Iterator zurück, sondern aus der Methode, die den Iterator aufgerufen hat, zum Beispiel
def test
puts "Eintritt in die Methode"
1.times { puts "Eintritt in den Block"; return } # Rückkehr aus Methode test
puts "Ausgang aus der Methode" # Zeile wird nie ausgeführt.
end
test
Eine Proc verhält sich wie ein Block; wenn Sie also eine Proc aufrufen, die eine
return
-Anweisung enthält, versucht sie, aus der Methode zurückzukehren, die den Block enthält, der in die Proc konvertiert wurde, zum Beispiel
def test
puts "Eintritt in die Methode"
p = Proc.new { puts "Eintritt ind die Proc"; return }
p.call # Aufruf der proc sorgt für Rückkehr aus der Methode.
puts "Ausgang aus der Methode" # Zeile wird nie ausgeführt.
end
test
Die Verwendung einer
return
-Anweisung in einer Proc ist allerdings gefährlich, weil Procs oft zwischen Methoden hin- und hergereicht werden. Zu dem
Weitere Kostenlose Bücher