ブロックを変数に割り当てることはできません。
ブロックは実際にはオブジェクトではありません。これらは、コードを高次のメソッドに渡すための特別な構文です。変数に割り当て、受け渡し、操作できる実行可能コードが必要な場合は、Proc
オブジェクトを使用する必要があります。
Proc
s には、ラムダと通常の proc の2 種類があります。これらは、引数バインディングのセマンティクスとセマンティクスという 2 つの側面で異なる動作をしますreturn
。ラムダは、メソッドのように引数をバインドし、メソッドからメソッドが返されるreturn
ように、ラムダから返されます。return
通常のプロシージャは、ブロックのように引数をバインドし、ブロックreturn
のように、プロシージャではなく、囲んでいるメソッドから戻りますreturn
。
Proc.new
通常のプロシージャは、ブロックを に渡すか、代わりに に渡すことで作成できますKernel#proc
。ラムダは、ブロックを渡すKernel#lambda
か、「安定したラムダ」リテラル構文を使用して作成できます。
lambda_object = ->param { puts param**2 }
Proc
s をブロックに、またはその逆に変換するために、Ruby には単項接頭辞&
修飾子があります。この修飾子は、パラメーター リストと引数リストでのみ有効です。パラメーターリストで使用すると、「ブロックを proc でラップし、この変数にバインドする」ことを意味します。引数リストで使用する場合。これは、「この proc をブロックにアンラップし (まだ proc でない場合は、to_proc
最初に呼び出して)、ブロック引数として渡す」ことを意味します。
(1..10).each(&lambda_object)
単項接頭辞修飾子がこのように使用されているのを見たことがないことに驚いています。&
実際にはかなり一般的です['1', '2'].map(&:to_s)
。
実行可能コードを表すもう 1 つのMethod
種類のオブジェクトは、オブジェクトです。sと同じインターフェイスの一部、特に 、 、Proc
など#call
を#to_proc
サポートしています。オブジェクトを取得するには 2 つの方法があります。メソッドを使用してそのレシーバーからレシーバーにバインドされているメソッドを取得するか、クラスからオブジェクトを取得します。またはモジュール (例: using ) を使用して、オブジェクトを返すレシーバーにバインドします。#arguments
#arity
Method
Object#method
UnboundMethod
Module#instance_method
UnboundMethod#bind
Method
Method
が実装されているため、単項接頭辞修飾子to_proc
を使用してブロックとしてメソッドに渡すことができます。&
# Warning: extremely silly example :-)
ary = []
(1..10).each(&ary.method(:<<))
ary
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
ary = []
(1..10).each(&Array.instance_method(:<<).bind(ary))
ary
# => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]