📌
Hash#to_proc について
#to_proc
メソッドは &
でブロック引数を渡したときに Ruby の内部で呼び出されるメソッドです。
class X
def to_proc
-> (value) { "hello, #{value}" }
end
end
x = X.new
# x.to_proc の結果をブロック引数として渡す(受け取る)
pp "homu".then(&x)
#to_proc
で一番有名なのは Symbol#to_proc
になりますかね。
.map(&:upcase)
も内部で :upcase.to_proc
がブロック引数として渡されるようになっています。
# Symbol#to_proc は引数をレシーバとして symbol の名前のメソッドを呼びだす
# 下記だと "mami".upcase が内部で呼び出される
pp :upcase.to_proc.call "mami"
# => "MAMI"
# :upcase.to_proc がブロック引数として渡される
pp "homu".then(&:upcase)
# => "HOMU"
普段何気なく使っている &
も内部ではこんな動きをしています。
Hash#to_proc
Symbol#to_proc
は有名なんですが他に #to_proc
が定義されているクラスで Hash#to_proc
があります。
これは Hash#[]
と同じような挙動の Proc
オブジェクトを返します。
homu = { id: 1, name: "homu", age: 14 }
# Hash#[] はキーを引数に受け取り、その値を返す
pp homu[:name] # => "homu"
# 対応するキーがなければ nil を返す
pp homu[:hoge] # => nil
# Hash#to_proc では Hash#[] と同じ挙動をする Proc を返す
pp homu.to_proc.call(:name) # => "homu"
pp homu.to_proc.call(:hoge) # => nil
わたしは未だに利用したことはないんですがどういうときに便利なんですかね〜。
homu = { id: 1, name: "homu", age: 14 }
# 配列の要素から Hash の値を抽出する
pp [:id, :name, :age].map(&homu)
# => [1, "homu", 14]
ちなみに Proc#call
は Proc#[]
でも呼び出せるので以下のように書くこともできます。
homu = { id: 1, name: "homu", age: 14 }
# より Hash っぽく添字アクセスでーの値を参照できる
pp homu.to_proc[:name] # => "homu"
pp homu.to_proc[:hoge] # => nil
Discussion