2009-09-06 16 views

Antwort

96

block ist nur eine lokale Variable, &block ist eine Referenz auf den Block, der an die Methode übergeben wird.

def foo(block = nil) 
    p block 
end 

foo # => nil 
foo("test") # => test 
foo { puts "this block will not be called" } # => nil 

def foo(&block) 
    p block 
end 

foo # => nil 
foo("test") # => ArgumentError: wrong number of arguments (1 for 0) 
foo { puts "This block won't get called, but you'll se it referenced as a proc." } 
# => #<Proc:[email protected]:20> 

Sie können auch &block verwenden, wenn Methoden Aufruf einer proc als Block auf eine Methode zu übergeben, so dass Sie Procs verwenden können, wie Sie Blöcke verwenden.

my_proc = proc {|i| i.upcase } 

p ["foo", "bar", "baz"].map(&my_proc) 
# => ["FOO", "BAR", "BAZ"] 

p ["foo", "bar", "baz"].map(my_proc) 
# => ArgumentError: wrong number of arguments (1 for 0) 

Der Variablenname block bedeutet nichts besonderes. Sie können &strawberries verwenden, wenn Sie möchten, ist das kaufmännische Und hier der Schlüssel.

Sie könnten this article hilfreich finden.

+28

+1 für '' '& erdbeeren''' – raycchan

+1

Ich füge hinzu: es ist ähnlich wie Sie den Splat (dh '*') Operator für Arrays verwenden:' def foo (* args) ; other_foo (* Argumente); Ende nimmt ein beliebiges Array von Argumenten auf und übergibt dann dasselbe Array an den inneren Funktionsaufruf. Mit Blöcken würde man 'def foo (& block); other_foo (& Block); Ende –

27

In einer Argumentliste übernimmt &whatever den Block, der an die Methode übergeben wurde, und umschließt ihn in einem Proc-Objekt. Der Proc wird in einer Variablen namens whatever gespeichert (wobei das der Name sein kann, den Sie nach dem kaufmännischen Und-Zeichen eingegeben haben, natürlich - normalerweise ist es "Block"). Nach einem Methodenaufruf verwandelt die &whatever Syntax einen Proc in einen Block. Also, wenn Sie eine Methode, wie so definieren:

def thing(&block) 
    thing2 &block 
end 

Sie eine Methode definieren, die einen Block nimmt und ruft dann eine andere Methode mit diesem Block.

16

Wenn Sie & vor dem Block nicht festlegen, erkennt Ruby seine Beziehung zu dem "Block", den Sie an die Funktion übergeben, nicht. Hier einige Beispiele.

def f(x, block); end 
f(3) { 2+2 } # gives an error, because "block" is a 
       # regular second argument (which is missing) 

def g(x, &block); end 
g(3) { 2+2 } # legal 

def h(x); end 
h(3) { 2+2 } # legal 

für die spätere Verwendung in einer Funktion:

def x(&block) # x is a 0 param function 
    y(block)  # y is a 1 param function (taking one "Proc") 
    z(&block)  # z is a 0 param function (like x) with the block x received 
end 

Also, wenn Sie z(&block) nennen es ist (fast !!) die gleiche wie z { yield } Aufruf: Sie haben soeben den Block in die nächste Funktion übergeben.

Verwandte Themen