Die Programmiersprache Ruby (German Edition)
den Variablen
k
und
v
zugewiesen:
k,v = [key, value]
Gemäß den Regeln der parallelen Wertzuweisung (siehe „4.5.5 Parallele Wertzuweisung“ ) wird ein einzelnes Array auf der rechten Seite extrahiert, und seine Elemente werden den mehreren Variablen auf der linken Seite zugewiesen.
Blockaufrufe funktionieren nicht genau wie parallele Wertzuweisungen. Stellen Sie sich einen Iterator vor, der zwei Werte an seinen Block übergibt. Gemäß den Regeln der parallelen Wertzuweisung könnten wir erwarten, dass wir in der Lage sind, einen Block mit einem einzelnen Parameter zu deklarieren und die beiden Werte automatisch in ein Array füllen zu lassen. Aber so funktioniert es nicht.
def two; yield 1,2; end # Iterator, der zwei Werte übergibt
two {|x| p x } # Ruby 1.8: Warnt und gibt [1,2] aus
two {|x| p x } # Ruby 1.9: Gibt 1 aus, keine Warnung
two {|*x| p x } # Jede Version: Gibt [1,2] aus; keine Warnung
two {|x,| p x } # Jede Version: Gibt 1 aus; keine Warnung
In Ruby 1.8 werden mehrere Argumente in ein Array gepackt, wenn es einen einzelnen Block-Parameter gibt, aber dieses Verhalten ist veraltet und erzeugt ein Warnmeldung. In Ruby 1.9 wird dem Block-Parameter der erste
yield
-Wert zugewiesen, und der zweite Wert wird stillschweigend ignoriert. Wenn wir möchten, dass mehrere
yield
-Werte in ein Array gepackt und einem einzelnen Block-Parameter zugewiesen werden, müssen wir dies explizit angeben, indem wir dem Parameter das Präfix
*
voranstellen, genau wie bei einer Methodendeklaration. (Siehe Kapitel 6 für eine gründliche Erklärung von Methodenparametern und Methodendeklaration.) Beachten Sie auch, dass wir den zweiten
yield
-Wert explizit verwerfen können, indem wir eine Block-Parameterliste deklarieren, die mit einem Komma endet, als wollten wir sagen: »Es gibt noch einen weiteren Parameter, aber der wird nicht verwendet, und ich möchte mich nicht damit plagen, einen Namen für ihn auszusuchen.«
Blockaufrufe verhalten sich in diesem Fall aber auch nicht genau wie parallele Wertzuweisungen. Wenn wir eine Methode mit einem Argument deklarieren und ihr dann zwei Werte übergeben, gibt Ruby nicht nur eine Warnung aus, sondern löst einen Fehler aus.
In Ruby 1.8 kann nur der letzte Block-Parameter ein
*
-Präfix haben. Ruby 1.9 lockert diese Beschränkung und erlaubt, dass ein beliebiger Block-Parameter unabhängig von seiner Position in der Liste ein
*
-Präfix haben darf:
def five; yield 1,2,3,4,5; end # 5 yield-Werte
five do |head, *body, tail| # Zusätzliche Werte ins Array body
print head, body, tail # Gibt "1[2,3,4]5" aus
end
Die Anweisung
yield
erlaubt klammerlose Hashes als letzten Argumentwert, und ebenso Methodenaufrufe (siehe „6.4.4 Hashes für benannte Argumente“ ). Das heißt: Wenn das letzte Argument von
yield
ein Hash-Literal ist, können Sie die geschweiften Klammern weglassen. Da es nicht üblich ist, dass Iteratoren mit
yield
Hashes übergeben, müssen wir ein Beispiel konstruieren, um dies zu demonstrieren:
def hashiter; yield :a=>1, :b=>2; end # Ohne geschweifte Klammern
hashiter {|hash| puts hash[:a] } # Gibt 1 aus
In Ruby 1.9 kann der letzte Block-Parameter ein & als Präfix erhalten, um festzulegen, dass er einen mit dem Blockaufruf verknüpften Block aufnehmen soll. Denken Sie jedoch daran, dass mit einem
yield
-Aufruf kein Block verknüpft sein muss. Wir werden in Kapitel 6 erfahren, dass ein Block in eine Proc konvertiert werden kann, und dass Blöcke mit Proc-Aufrufen verknüpft werden können . Das folgende Codebeispiel dürfte einen Sinn ergeben, sobald Sie Kapitel 6 gelesen haben:
# Diese Proc erwartet einen Block
printer = lambda {|&b| puts b.call } # Rückgabewert von b ausgeben
printer.call { "hi" } # Dem Block einen Block übergeben!
Ein wichtiger Unterschied zwischen Block-Parametern und Methodenparametern besteht darin, dass Block-Parametern nicht wie Methodenparametern Standardwerte zugewiesen werden dürfen. Das heißt, es ist nicht legal, das hier zu schreiben:
[1,2,3].each {|x,y=10| print x*y } # SyntaxError!
Ruby 1.9 definiert eine neue Syntax zur Erzeugung von
Proc
-Objekten, und diese neue Syntax erlaubt Standardwerte für Argumente. Details müssen warten, bis Sie in Kapitel 6 etwas über Proc-Objekte gelesen haben, aber dieser Code kann wie folgt umgeschrieben werden:
[1,2,3].each &->(x,y=10) { print x*y } # Gibt "102030" aus
5.5 Den Steuerungsablauf modifizieren
Zusätzlich zu Fallentscheidungen, Schleifen und Iteratoren unterstützt Ruby eine Reihe
Weitere Kostenlose Bücher