Procクラスふりかえり
Procクラスはブロックとして記述された手続きを持ち運ぶことができるクラスです。
Proc.newメソッドまたはprocメソッドにブロックを与えると、そのブロックを保持するProcオブジェクトが作成できます。
callで呼び出すと実行されます。
hello_1 = Proc.new do |name|
puts "Hello,#{name}."
end
hello_2 = proc do |name| #procメソッドを使う場合は小文字
puts "Hello,#{name}."
end
>> hello_1.call("World")
Hello,World.
=> nil
>> hello_2.call("Ruby")
Hello,Ruby.
=> nil
lambdaは、Procオブジェクトを生成するメソッドです。
Proc.newメソッドまたはprocメソッドと比較すると、lambdaメソッドで作成したProcオブジェクトのほうがメソッド呼び出しに近い動作になります。
lambdaメソッドとの違い
■引数の数が厳密にチェックされます
Proc.newでつくったProcオブジェクトは、call呼び出しを受ける際に、引数とブロック変数の数が違っても問題ありません。
?> prc1 = Proc.new do |a,b,c| ?> p [a,b,c] >> end => #<Proc:0x000000010337e7a0 (irb):13> >> prc1.call(1,2) [1, 2, nil] => [1, 2, nil] >> prc1.call(1) [1, nil, nil] => [1, nil, nil] >> prc1.call(1,2,3,4) [1, 2, 3] => [1, 2, 3]
一方、lambdaではエラーになります。
?> prc2 = lambda do |a,b,c|
?> p [a,b,c]
>> end
=> #<Proc:0x0000000103398470 (irb):22 (lambda)>
>> prc2.call(1,2)
(irb):22:in `block in <top (required)>': wrong number of arguments (given 2, expected 3) (ArgumentError)
from (irb):25:in `<main>'
from /Users/tokudome/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.9.1/exe/irb:9:in `<top (required)>'
from /Users/tokudome/.rbenv/versions/3.2.2/bin/irb:25:in `load'
from /Users/tokudome/.rbenv/versions/3.2.2/bin/irb:25:in `<main>'
>> prc2.call(1,2,3)
[1, 2, 3]
=> [1, 2, 3]
>> prc2.call(1,2,3,4)
(irb):22:in `block in <top (required)>': wrong number of arguments (given 4, expected 3) (ArgumentError)
from (irb):27:in `<main>'
from /Users/tokudome/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.9.1/exe/irb:9:in `<top (required)>'
from /Users/tokudome/.rbenv/versions/3.2.2/bin/irb:25:in `load'
from /Users/tokudome/.rbenv/versions/3.2.2/bin/irb:25:in `<main>'
■returnを使えます
lambdaで書くと以下になります。
?> def power_of(n) ?> lambda do |x| ?> return x ** n ?> end >> end => :power_of >> >> cube = power_of(3) >> p cube.call(5) 125 => 125
Proc.newを使う場合はエラーになります。
?> def power_of(n)
?> Proc.new do |x|
?> return x ** n
?> end
>> end
=> :power_of
>>
>> cube = power_of(3)
=> #<Proc:0x0000000103dbb038 (irb):14>
>> p cube.call(5)
(irb):15:in `block in power_of': unexpected return (LocalJumpError)
from (irb):20:in `<main>'
from /Users/tokudome/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/irb-1.9.1/exe/irb:9:in `<top (required)>'
from /Users/tokudome/.rbenv/versions/3.2.2/bin/irb:25:in `load'
from /Users/tokudome/.rbenv/versions/3.2.2/bin/irb:25:in `<main>'
>>