RubyのProcとlamdaについて

概要

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 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける 手続きオブジェクトを抜ける

参考