Rubyのブロックについての理解
実際手を動かすと理解しやすいので、書いてみるのがおすすめ。
基本
def give_me_block yield # yieldで暗黙引数のブロックが実行される感じ end give_me_block do # --- ここから p 'Hello, block1' p 'Hello, block2' p 'Hello, block3' # --- ここまでを def give_me_blockに渡す end
do〜end
で囲んだところをProcオブジェクトにしてgive_me_block
に渡し、yield
ではProcオブジェクトを.call
している
結果
"Hello, block1" "Hello, block2" "Hello, block3"
ブロックを受け取るときのルール
- &をつけることでブロックをうけとることを明示している
- 引数に渡すことができるブロックはひとつまで
- 引数のブロックは最後に定義されていないとダメ
- ブロックはProcのオブジェクト。
.call
で実行できる
# def give_me_block_with_param(&block1, &block2) # これはダメ # def give_me_block_with_param(&block1, params) # これはダメ def give_me_block_with_param(params, &block1) p params p block1.class block1.call end
引数の渡し方
give_me_block_with_param
は引数ひとつ(とブロック)なので、そもそもカンマで区切ることはできない
# give_me_block_with_param 123, do #これはダメ give_me_block_with_param 123 do p 'Block1' end
結果
123 Proc "Block1"
- do〜endの代わりに {〜}するときは、どこまでが引数、どこからブロックなのかわからないので括弧をつけてあげる
# give_me_block_with_param 456 { これはダメ give_me_block_with_param (456) { p 'Block2' }
結果
456 Proc "Block2"
ブロックをうけとるメリットのひとつは、見た目そのままで後処理など拡張ができること
def sum_and_exec_block(x, y) z = x + y z = yield z if block_given? z end p sum_and_exec_block(1, 2) # 3 # ブロックの引数valueで受け取るのは上の yieldの引数 z hoge = sum_and_exec_block(10, 20) do |value| value + 10 end p hoge # 40 p( sum_and_exec_block(10, 20) { |value| value + 20 }) # 50