言語
日本語
English

Caution

お使いのブラウザはJavaScriptが無効になっております。
当サイトでは検索などの処理にJavaScriptを使用しています。
より快適にご利用頂くため、JavaScriptを有効にしたうえで当サイトを閲覧することをお勧めいたします。

Ruby辞典

  1. トップページ
  2. Ruby辞典
  3. Proc.new / proc / lambda / ->

Proc.new / proc / lambda / ->

対応: Ruby 1.9(2007)

ProcとLambdaはブロックをオブジェクト化したものです。変数に代入したり、複数回呼び出したりできます。

構文

# Proc オブジェクトを作成します。
procedure = Proc.new { |arg| 処理 }
procedure = proc { |arg| 処理 }

# Lambda を作成します。
func = lambda { |arg| 処理 }
func = ->(arg) { 処理 }  # アロー構文(Ruby 1.9以降)

# Proc / Lambda を呼び出します。
procedure.call(arg)
procedure.(arg)    # .call の省略形
procedure[arg]     # [] でも呼び出せます。

ProcとLambdaの違い

項目ProcLambda
引数の数チェックチェックしない(余分な引数は無視)厳密にチェックする
returnの動作呼び出し元メソッドからも返るLambda 内だけから返る
lambda?falsetrue

サンプルコード

sample_proc_lambda.rb
# Proc を作成して呼び出します。
greet = Proc.new { |name| puts "こんにちは、#{name}さん!" }
greet.call("八神庵")       # こんにちは、八神庵さん!
greet.("テリー・ボガード")  # こんにちは、テリー・ボガードさん!

# Lambda(アロー構文)を作成します。
square = ->(n) { n ** 2 }
puts square.call(4)  # 16
puts square.(5)      # 25

# Lambda は引数の数を厳密にチェックします。
# 以下はエラーになります。
# square.call(4, 5)  # ArgumentError: wrong number of arguments

# Proc は引数が少なくても nil で補完します。
add = Proc.new { |a, b| puts (a.to_i + b.to_i) }
add.call(3, 4)  # 7
add.call(3)     # 3(b は nil → 0 として計算)

# Lambda を配列に格納して使います。
transforms = [
  ->(s) { s.upcase },
  ->(s) { s.reverse },
  ->(s) { s.gsub("o", "0") }
]
text = "hello"
transforms.each { |t| puts t.call(text) }
ruby proc_lambda.rb
こんにちは、八神庵さん!
こんにちは、テリー・ボガードさん!
16
25
7
3
HELLO
olleh
hell0

概要

ProcとLambdaはどちらもブロックをオブジェクト化しますが、引数チェックと『return』の動作が異なります。一般的には安全なLambdaをお勧めします。アロー構文『->()』は簡潔に書けるため現代のRubyコードでよく使われます。

Proc/Lambdaを変数に格納することで、コールバック・ストラテジーパターン・遅延評価などを実現できます。ストラテジーパターンとは、処理のアルゴリズムを切り替え可能にするデザインパターンです。Proc内で『return』を使うと呼び出し元メソッドまで抜けてしまうため、Procを使う場合は『return』を避けるか、最後の式の値が戻り値として使われることを意識してください。

記事の間違いや著作権の侵害等ございましたらお手数ですがまでご連絡頂ければ幸いです。