Procオブジェクト

パーフェクトRuby (PERFECT SERIES 6)

パーフェクトRuby (PERFECT SERIES 6)

Proc#curry がとてもわかりやすい記載になっていました。
また、例のややこしいやつも一部忘れていたのでメモ。
 
どっち使うよという話だと
Procオブジェクトで私自身は嵌った経験はなく(Proc.new, Kernel#proc が欲しいケースがない)
「->」というsyntax sugarが用意されていることからlambdaで書くことが多いです。
基本lambdaで統一しておいて、Proc.new, Kernel#proc 欲しい場合のみ、 そっちで書くという方針にしています。

8-1-6. Proc#curry

引数として「x」と「y」のような複数の引数をとる関数に、「x」だけ渡して「y」を引数してとる関数を新たに作ることをカリー化といいます。

add = Proc.new { |x,y| x+y }
inc = add.curry.(1)
inc.(2) # => 3

8-3. Proc.new / Kernel.proc / Kernel.lamda

return / break

メソッド return break
Proc.new, Kernel#proc メソッドを抜ける 例外が発生する
Kernel.lambda 制御を抜ける 制御を抜ける

nextで中断

処理の中断には next を利用すると、どちらにも対応。

def wrap_method(proc_or_lambda)
  x = proc_or_lambda.call(1)
  x.to_s
end

wrap_method proc { |x| next; x.succ }
wrap_method lambda { |x| next; x.succ }

引数の違い

Proc.new, Kernel#proc は

  • 仮引数の数より多く引数が渡された場合は無視する
  • 引数の数が足りない場合、足りない引数にはnilが渡される
  • 複数の仮引数が定義されている時に配列が1つだけ渡されると展開される

Kernel#lambda は ArugumentErrorが発生する。

Proc#lambda? を使うと判断可能。