Caution
お使いのブラウザはJavaScriptが実行できない状態になっております。
当サイトはWebプログラミングの情報サイトの為、
JavaScriptが実行できない環境では正しいコンテンツが提供出来ません。
JavaScriptが実行可能な状態でご閲覧頂くようお願い申し上げます。
Proc.new / proc / lambda / ->
ProcとLambdaはブロックをオブジェクト化したものです。変数に代入したり、複数回呼び出したりできます。
構文
# Proc オブジェクトを作成します。
手続き = Proc.new { |引数| 処理 }
手続き = proc { |引数| 処理 }
# Lambda を作成します。
関数 = lambda { |引数| 処理 }
関数 = ->(引数) { 処理 } # アロー構文(Ruby 1.9以降)
# Proc / Lambda を呼び出します。
手続き.call(引数)
手続き.(引数) # .call の省略形
手続き[引数] # [] でも呼び出せます。
ProcとLambdaの違い
| 項目 | Proc | Lambda |
|---|---|---|
| 引数の数チェック | チェックしない(余分な引数は無視) | 厳密にチェックする |
| returnの動作 | 呼び出し元メソッドからも返る | Lambda 内だけから返る |
| lambda? | false | true |
サンプルコード
# Proc を作成して呼び出します。
挨拶 = Proc.new { |名前| puts "こんにちは、#{名前}さん!" }
挨拶.call("田中") # こんにちは、田中さん!
挨拶.("山田") # こんにちは、山田さん!
# Lambda(アロー構文)を作成します。
二乗 = ->(n) { n ** 2 }
puts 二乗.call(4) # 16
puts 二乗.(5) # 25
# Lambda は引数の数を厳密にチェックします。
# 以下はエラーになります。
# 二乗.call(4, 5) # ArgumentError: wrong number of arguments
# Proc は引数が少なくても nil で補完します。
足し算 = Proc.new { |a, b| puts (a.to_i + b.to_i) }
足し算.call(3, 4) # 7
足し算.call(3) # 3(b は nil → 0 として計算)
# Lambda を配列に格納して使います。
変換処理 = [
->(s) { s.upcase },
->(s) { s.reverse },
->(s) { s.gsub("o", "0") }
]
テキスト = "hello"
変換処理.each { |処理| puts 処理.call(テキスト) }
概要
ProcとLambdaはどちらもブロックをオブジェクト化しますが、引数チェックと『return』の動作が異なります。一般的には安全なLambdaをお勧めします。アロー構文『->()』は簡潔に書けるため現代のRubyコードでよく使われます。
Proc/Lambdaを変数に格納することで、コールバック・ストラテジーパターン・遅延評価などを実現できます。Proc内で『return』を使うと呼び出し元メソッドまで抜けてしまうため、Procを使う場合は『return』を避けるか、最後の式の値が戻り値として使われることを意識してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。