はじめに
Rubyでブロックをオブジェクト化したいとき、Procクラスが用意されています。Procオブジェクトの生成方法は複数ありますが、今回はそれらの引数の扱いの違いについて、学んだことをまとめたいと思います。(Ruby2.5.1)
Procオブジェクトの生成方法
Procオブジェクトの生成方法は複数ありますが、その中でも今回は以下の4つを例に挙げたいと思います。
#①Procクラスのnewメソッドを使う
Proc.new {...}
#②Kernelモジュールのprocメソッドを使う
proc {...}
#③ラムダリテラルを使う
-> {...}
#④Kernelモジュールのlambdaメソッド を使う
lambda {...}
ここでは①と②をProc.new、③と④をラムダと呼ぶことにします。
ラムダのほうが引数の扱いに厳密である
Proc.newとラムダでは、ラムダの方が引数のチェックが厳しく、引数に過不足があるとエラーが発生します。
実際のコード
a,bの2つの引数を取り、それらを表示するProcオブジェクトを作ります。
###・ Proc.new
引数の過不足による引数エラーは発生しません。
proc = Proc.new { |a, b| p "#{a}, #{b}" }
proc.call(1) #=> "1, "
proc.call(1, 2, 3) #=> "1, 2"
proc = proc { |a, b| p "#{a}, #{b}" }
proc.call(1) #=> "1, "
proc.call(1, 2, 3) #=> "1, 2"
###・ ラムダ
引数に過不足があると引数エラーが発生します。
lambda = -> (a, b) { p "#{a}, #{b}" }
lambda.call(1)
#=> ArgumentError: wrong number of arguments (given 1, expected 2)
lambda.call(1, 2, 3)
#=> ArgumentError: wrong number of arguments (given 3, expected 2)
lambda = lambda { |a, b| p "#{a}, #{b}" }
lambda.call(1)
#=> ArgumentError: wrong number of arguments (given 1, expected 2)
lambda.call(1, 2, 3)
#=> ArgumentError: wrong number of arguments (given 3, expected 2)
引数の取扱の厳密さを確かめる
Procオブジェクトの引数の取扱の厳密さを確認したいとき、.lambda?
メソッドが使えます。
引数の扱いが厳密であれば、.lambda?
メソッドはtrue
を返します。
proc = Proc.new { |a, b| p "#{a}, #{b}" }
proc.class #=> Proc
proc.lambda? #=> false
lambda = -> (a, b) { p "#{a}, #{b}" }
lambda.class #=> Proc
lambda.lambda? #=> true
まとめ
Proc.newとラムダでは、ラムダの方が引数の扱いが厳密で、.lambda?
メソッドで引数の取扱の厳密さを確認することができました。