技術ブログ

(技術系中心)基本自分用備忘録なので、あくまで参考程度でお願いします。

ブロックをメソッドの引数にする方法

ブロックをメソッドの引数にする方法

Rubyではブロックをメソッドの引数として渡すことが可能です。

def メソッド名(&引数)
 引数.call
end

ブロックを引数として受け取る場合は、引数の前に&をつけます。 また、そのブロックを実行する場合はcallメソッドを使います。  ( 引数のblockはProcオブジェクトです)

def hoge(&block)
  puts 'hoge'
  text = block.call('huge')
  puts text
  puts 'hoge'
end

メソッドの引数に(&block)を作成したので、メソッド呼び出し時にブロックを渡す形でメソッドを読んでみましょう。

hoge do |text|
  text 
end
# => hoge
# => hugehuge
# => hoge

応用編

['ruby','java','perl'].map{|s|s.upcase}#=>["RUBY","JAVA","PERL"]
['ruby','java','perl'].map(&:upcase)#=>["RUBY","JAVA","PERL"]

①&:upcaseはシンボルの:upcaseに対してto_procメソッドを呼び出す。
②シンボルの:upcaseがProcオブジェクトに変換され、mapメソッドにブロックとして渡される。
③上記②で作ったProcオブジェクトはmapメソッドから配列の各要素を実行時の第1引数として受け取る。
第1引数はupcaseメソッドのレシーバとなる。つまり、配列の各要素に対してupcaseメソッドを呼び出す。
④mapメソッドはProcオブジェクトの戻り値を順に新しい配列に詰め込む。
⑤上記③と④のコンビネーションにより、配列の各要素が大文字に変換された新しい配列がmapメソッドの戻り値になる。

参考: プロを目指す人のためのRuby入門(伊藤 淳一)