🐡
Ruby の Hash#default について
Ruby の Hash ではキーの要素が存在しなかった場合には nil
を返すようになっています。
hash = {}
pp hash[:key] # => nil
このデフォルト値は Hash#default
の値に依存しており、この値を意図的に書き換える事もできます。
hash = {}
# デフォルトでは nil に割り当てられている
pp hash.default # => nil
pp hash[:key] # => nil
# Hash#default= でデフォルト値を書き換えることもできる
# デフォルト値を 0 にする場合
hash.default = 0
pp hash[:key] # => 0
注意点
Hash#default
なんですがこれは『要素がみつからなかったときには同じオブジェクト』を返します。
hash = {}
default = "homu"
hash.default = default
# 全部同じオブジェクトを参照する
pp default.__id__ # => 60
pp hash[0].__id__ # => 60
pp hash[1].__id__ # => 60
なので、どれか1つでも破壊的な変更を行うと全ての結果に影響を与えます。
hash = {}
default = "homu"
hash.default = default
hash[0].upcase!
# 全ての値が変わる
pp default # => "HOMU"
pp hash[0] # => "HOMU"
pp hash[1] # => "HOMU"
もし、上記のような副作用を防ぎたい場合は Hash.new
にブロック引数を渡して都度初期化する必要があります。
# キーの要素がみつからなかったときにブロックが呼び出される
hash = Hash.new { |hash, key| hash[key] = "homu" }
# 別のオブジェクトを参照する
pp hash[0].__id__ # => 60
pp hash[1].__id__ # => 80
# 他の要素に影響を与えない
hash[0].upcase!
pp hash[0] # => "HOMU"
pp hash[1] # => "homu"
Discussion