2009-09-06 9 views

答えて

96

は、ローカル変数です。&blockは、メソッドに渡されたブロックへの参照です。メソッドにブロックとしてPROCを渡すためのメソッドを呼び出すときに、あなたがブロックを使用すると同じようにprocsのを使用できるように

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> 

また、&blockを使用することができます。

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) 

変数名blockは特別な意味を持ちません。もしあなたが好きなら、&strawberriesを使うことができます。アンパサンドがここの鍵です。

this articleが参考になる場合があります。

+28

+1 '' '&strawberries''' – raycchan

+1

これは配列にスプラット(すなわち '*')演算子を使う方法に似ています:def foo(* args) ; other_foo(* args); end'は引数の任意の配列をとり、その同じ配列を内部関数呼び出しに渡します。ブロックでは、 'def foo(&block);を実行します。 other_foo(&ブロック);終わり –

27

引数リストで、&whateverは、メソッドに渡されたブロックを取得し、Procオブジェクトにラップします。 Procは、whateverという変数に格納されています(ここでは、アンパサンドの後に入力した名前が使用できます)。通常は「ブロ​​ック」です。メソッド呼び出し後、&whatever構文はProcをブロックに変換します。だから、そうのようなメソッドを定義する場合:あなたは、そのブロックを持つ別のメソッドを呼び出して、ブロックを取り、メソッドを定義している

def thing(&block) 
    thing2 &block 
end 

16

ブロック前に&を設定しないと、Rubyは関数に渡す「ブロック」との関係を認識しません。ここにいくつかの例があります。関数内で後で使用するため

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 

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 

あなたがz(&block)を呼び出すのであれば、それは(ほぼ!!)z { yield }を呼び出すのと同じです:あなたは次の関数にブロックを渡します。

関連する問題