概要
RubyのProcとlamdaについてかく。
Procとは
ブロックをオブジェクト化したもの。ブロックはオブジェクトではない。
このオブジェクトは手続きオブジェクトと呼ばれ、Procクラスのインスタンスとして表現される。
Proc.newまたはprocによって手続きオブジェクトを生成できる。
lamdaとは
Procオブジェクトを作成するための構文で、手続きオブジェクトを生成する。
lamdaまたは->{}によって手続きオブジェクトを生成できる。
Procとlamdaの違い
引数の扱いが異なる
Procの場合は緩いが、lamdaの場合は厳格である。
ジャンプ構文(return、next、break)の挙動
次のような違いがある。
| return | next | break | |
|---|---|---|---|
| Proc.new | メソッドを抜ける | 手続きオブジェクトを抜ける | 例外が発生する |
| proc | メソッドを抜ける | 手続きオブジェクトを抜ける | 例外が発生する |
| lambda | 手続きオブジェクトを抜ける | 手続きオブジェクトを抜ける | 手続きオブジェクトを抜ける |
歴史的経緯
jp.quora.com - rubyのブロックとProcに本質的な違いはありますか?より引用。
補足として、歴史的な経緯を記述しておくと、ブロック(とyieldによる呼び出し)がまず最初に導入され、それから、それをオブジェクトするために Proc.new が誕生しました。また、無名関数相当を実現するために lambda メソッド(と proc メソッド)が導入されました。
その後、ブロック引数(&引数)が導入されることで Proc.new の必要性が薄れ、lambda式(->)が導入されることで、lambdaやprocメソッドの必要性が薄れ、それらは現在ではほとんど使われなくなっています。たぶん、将来これらのメソッドは削除されるでしょう。Rubyの歴史による変化を感じさせますね。
5年前の回答ではあるが、lamda式を使っておけば大抵問題ないということだろうか。
孤児的なオブジェクトの挙動
手続きオブジェクトがメソッドの外で使用されるようなケースにおいても違いがある。
| return | next | break | |
|---|---|---|---|
| Proc.new | 例外が発生する | 手続きオブジェクトを抜ける | 例外が発生する |
| proc | 例外が発生する | 手続きオブジェクトを抜ける | 例外が発生する |
| lambda | 手続きオブジェクトを抜ける | 手続きオブジェクトを抜ける | 手続きオブジェクトを抜ける |