よく業務でブロックの代わりに&:を使って書くことがあるが、一体どういうことが起こっているのかを調べたのでまとめてみました。
SymbolのProc変換
まずワンコールブロックを使って書いた例を挙げる。
names = ['bob', 'bill', 'heather']
names.map{ |name| name.capitalize } #=> ["Bob", "Bill", "Heather"]
これをシンボルを使ってワンコールブロックに変換するようにするにはto_procメソッドと&修飾子を使う。to_procメソッドはシンボルをprocオブジェクトに変換するメソッドで&修飾子はProcオブジェクトをブロックへ変換する。
Class Symbol
def to_proc
Proc.new { |x| x.send(self) }
end
end
names = ['bob', 'bill', 'heather']
names.map(&:capitalize.to_proc) #=> ["Bob", "Bill", "Heather"]
&修飾子はすべてのオブジェクトに適応できる。to_procを一度呼び出してProcにしてブロックへと変換しているからだ。よって、次のように書くことができる。
names = ['bob', 'bill', 'heather']
names.map(&:capitalize) #=> ["Bob", "Bill", "Heather"]
これはSymbolのProc変換と呼ばれるRubyのテクニックである。
以上を踏まえると、以下の省略であると考えることができる。
names.map do |name|
name.send(:capitazize)
end
参考
- メタプログラミング
- https://docs.ruby-lang.org/ja/latest/method/Symbol/i/to_proc.html