Bye Bye Moore

PoCソルジャーな零細事業主が作業メモを残すブログ

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#== と同じ働きをしますが、 この挙動はサブクラスで所属性のチェックを実現するため 適宜再定義されます」

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