Help us understand the problem. What is going on with this article?

Proc.newとラムダは引数の扱いが異なる

More than 1 year has passed since last update.

はじめに

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

https://docs.ruby-lang.org/ja/latest/method/Proc/i/lambda=3f.html

まとめ

Proc.newとラムダでは、ラムダの方が引数の扱いが厳密で、.lambda?メソッドで引数の取扱の厳密さを確認することができました。

参考文献

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away