Rubyのブロックについて
Rubyにはブロックというものがある。
ブロックは「処理の集合体」
無名関数とかラムダ式とかクロージャのようなもの
ブロックはメソッドに渡すことでしか存在できない
変数とかに入れることはできない
ブロックはdo ... endで囲うか、 {| e | ...}で囲うかの2種類
code:rb
# { ... } がブロック
# do ... endがブロック
e + 1
end
# NG
a = { |e| e + 1 }
ブロックの呼び出し
yieldを使う
code: rb
def hoge
yield(100)
end
hoge { |e| e + 1 } # => 101
ブロックとは別に引数も渡せる
code:rb
def hoge(a)
puts a
yield(100)
end
hoge(1000) { |e| e + 1 } # => 101
# => "1000" が出力される
&blockを使う
code:rb
def hoge(&block)
block.call(100)
end
hoge { |e| e + 1 } # => 101
Procを使えば変数に格納可能
code:rb
block = Proc.new { |e| e + 1 }
block.call(1000)
=>1001
Procからブロックへの変換
Procをブロックとしてメソッドに渡したくなる時に利用できる
code:rb
plus_100 = proc { |e| e + 100 }
1,2,3.map(plus_100) # => Error! しかしこれはエラーになります。
なぜならplus_100はProcオブジェクトであってブロックではないからです。
Procオブジェクトをブロックに変換するためには&を使います。
code:rb
plus_100 = proc { |e| e + 100 }
このように、&をProcオブジェクトの前につけることによって、Procオブジェクトを「展開」し、ブロックとしてメソッドに渡すことができます。
似たようなものにlabmdaというのがあるが使い方は基本同じ
code:rb
test2 = lambda {|e| e + 1}
test2.call(100)
=> 101
labmdaの場合引数のかずが異なるとエラーを起こす
labmdaとprocはどちらもProcオブジェクト