📖
[Feature #20818] Hash#store にブロックを渡せるようにする提案
[Feature #20818] Allow passing a block to Hash#store (to update current value)
-
Hash#store
にブロックを渡せるようにする提案 -
Hash#store
はHash#[]=
と同等で特定のキーに値を割り当てるメソッドです
hash = {}
hash.store(:name, "homu")
pp hash
# => {:name=>"homu"}
-
Hash#store
にブロックを渡した場合は以下のような値をブロックの引数で受け取り、ブロックの戻り値がそのキーに割り当てられます- ブロックの引数に現在の値が渡される
- 現在の値がなければ
Hash#default
の値が渡される
hash = { name: "homu" }
# :name のキーに対して値を割り当てる
# ブロックの引数は現在の値を受け取る
# ブロックの戻り値が新しい値として割り当てられる
hash.store(:name) { |v|
v # => "homu"
"mami"
}
hash[:name] # => "mami"
# キーがなければ Hash#default の値がブロックで渡される
# 意図的に設定されていなければ `nil` を受け取る
hash.store(:age) { |v|
v # => nil
14
}
hash[:age] # => 14
# #default の値に依存して設定もできる
hash.default = 100
hash.store(:id) { |v|
v # => 100
v + 1
}
hash[:id] # => 101
- モチベーションとしては例えばキーがない場合に次のように
Hash#[]=
とHash#[]
を呼び出すことがあると思うんですが
hash[:name] = hash[:name] || "default name"
- 今回の
Hash#store
を使うと以下のようにかけるのでパフォーマンスがよい、みたいなところがモチベーションとしてあるみたいです
# こっちだとメソッド呼び出しが1つだけになる
hash.store(:name) { _1 || "default name" }
- PR もすでにあり実際にどれぐらいパフォーマンスが向上するのかと安全なのかどうか(ブロック内で他のキーの値を書き換えた場合にどうなるのか)みたいなところがコメントされています
- 個人的には
hash[:name] ||= "default name"
の書き味が好きなんですがどれぐらいパフォーマンスを気にする必要がありそうなんですかねー
Discussion