Bye Bye Moore

猫マンション建築の野望を胸に零細事業主として資本主義の荒波に漕ぎ出したアラサー男の技術メモ

Procの結果を受け取りたいなら===を使う

Proc.newの実行結果を受け取る

Procクラスの結果を受け取りたいときには、===を使います。

$ irb
> buff = Proc.new { puts "u" }
=> #<Proc:0x007fb063c3a008@(irb):1>

> buff === Proc.new { puts "u" }
u
=> nil

> c = Proc.new {|a,b| a * b }
=> #<Proc:0x007fb063901ff8@(irb):33>
> c === [10, 8]
=> 80

lambdaの挙動は少し違う

> buff = lambda { puts "u" }
=> #<Proc:0x007fb063c2bcb0@(irb):4 (lambda)>

> buff === lambda { puts "u" }
u
=> nil
> c = lambda { |x,y| x * y}
=> #<Proc:0x007fb063b25a28@(irb):67 (lambda)>

> c === [2,7]
ArgumentError: wrong number of arguments (1 for 2)
	from (irb):67:in `block in irb_binding'
	from (irb):68:in `==='
	from (irb):68
	from /Users/shuzo/.rbenv/versions/1.9.3-p448/bin/irb:12:in `<main>'

Proc.newもlambdaもProcクラスのインスタンスを取ります。
後者の方が厳密みたいです。
今回のように===で実行してくれませんし、引数が少ないと止まります。

おまけ

===はcase文の条件比較で内部的に呼び出されている子です。
ぱっと見==と同じような挙動を取りますが、クラス毎に再定義される事があります。
公式によると

「このメソッドは case 文での比較に用いられます。 デフォルトは Object#== と同じ働きをしますが、 この挙動はサブクラスで所属性のチェックを実現するため 適宜再定義されます」

使いこなせるとドヤリングが捗りそうですね(