ryudai.rb第2回が無事に終わりました。
今回は4人と前回より参加者は減りましたが、発表の内容の質は上がっていたいました。
今回の発表者はatton君です。
atton君の発表資料
https://github.com/atton-/ryudairb_002
今回はProcとブロック、イテレータについての発表でした。
Procについては「処理をオブジェクトとして扱う」ことができます。
例えば
siman = Proc.new{ puts "hello world" } siman.call
hello world
こんな感じでProc.newのブロック文の中身をそのままsimanという変数に入れて、それをcallすることでsimanの中にある「puts "hello world"」を呼び出すといった処理を行なっています。
処理をオブジェクト化する方法は他にもあって
siman = lambda { puts "hello world" } siman.call
hello world
だったり
siman = -> { puts "hello world" } siman.call
hello world
だったりできます。
ちなみに「lambda」と「->」は同じ意味なので気にしないで大丈夫です。
Procとlambdaの違いについては大きく分けて2つあり1つは
・return文の抜け方が違う
lambdaの場合はブロック文の中の処理から抜ける
def siman_lambda siman = lambda { return 10 } p siman.call end siman_lambda
10
この場合はlambdaのブロック文の中の処理からぬけるため、returnされる値である10がpメソッドによって表示されています。
Procの場合は「callを実行した場所からのreturnとなる」
def siman_proc siman = Proc.new { return 10 } p siman.call end siman_proc
この場合は何も表示されない。なぜならProcでのreturnは「callされた場所からのreturn」になるのでsiman_procのreturnとして実行されるからである。なので
def siman_proc siman = Proc.new { return 10 } siman.call end p siman_proc
10
こんな風に書いてあげるとちゃんと表示してくれる。
これにハマるとろくなことが無い。解決法としては「returnを使わない」らしい。
2つ目の違いは
・引数の厳密差
Procとlambdaは両方共ブロック引数をとることができるのだが、Procは厳密に与えなくても実行できる。
def siman_proc siman = Proc.new {|first, second| puts "first argument is #{first}" puts "second argument is #{second}" } siman.call(1,2) siman.call(1) end siman_proc
first argument is 1 second argument is 2 first argument is 1 second argument is
2回目のcallについては、2つ目の引数がないため何も表示されていないが実行はされている。
一方lambdaは引数の数があっていない場合はちゃんとエラーを出す。
def siman_lambda siman = lambda {|first, second| puts "first argument is #{first}" puts "second argument is #{second}" } siman.call(1,2) siman.call(1) end siman_lambda
first argument is 1 second argument is 2 lambda.rb:3:in `block in siman_lambda': wrong number of arguments (1 for 2) (ArgumentError) from lambda.rb:7:in `call' from lambda.rb:7:in `siman_lambda' from lambda.rb:10:in `<main>'
Procとlambdaの大きな違いはこんな感じ。
個人的にはlambdaの方が好きです。