hash = Hash.new(Hash.new([]))
hash[1][2] << 3
hash[1][2] # => [3]
hash # => {}
hash.keys # => []
hash.values # => []
どうしたの?Ruby の隠しデータ (1.9.3p125)
hash = Hash.new(Hash.new([]))
hash[1][2] << 3
hash[1][2] # => [3]
hash # => {}
hash.keys # => []
hash.values # => []
どうしたの?Ruby の隠しデータ (1.9.3p125)
どうしたの?Ruby の隠しデータ (1.9.3p125)
Ruby はデータもドキュメントも隠しません。
Hash
キーがハッシュに見つからない場合は常に、コンストラクターに渡すデフォルト値が返されます。しかし、このデフォルト値が実際に単独でハッシュに格納されることはありません。
必要なものを取得するには、Hash
コンストラクターをブロックで使用し、デフォルト値を自分でハッシュに格納する必要があります (ネストされたハッシュの両方のレベルで):
hash = Hash.new { |hash, key| hash[key] = Hash.new { |h, k| h[k] = [] } }
hash[1][2] << 3
p hash[1][2] #=> [3]
p hash #=> {1=>{2=>[3]}}
p hash.keys #=> [1]
p hash.values #=> [{2=>[3]}]
それは簡単です。Hash コンストラクターにオブジェクトを渡すと、そのハッシュで欠落しているすべてのキーの既定値になります。興味深いのは、この値が可変であることです。観察:
hash = Hash.new(Hash.new([]))
# mutate default value for nested hash
hash[1][2] << 3
# default value in action
hash[1][2] # => [3]
# and again
hash[1][3] # => [3]
# and again
hash[1][4] # => [3]
# set a plain hash (without default value)
hash[1] = {}
# what? Where did my [3] go?
hash[1][2] # => nil
# ah, here it is!
hash[2][3] # => [3]
これをirbで試してみます。Seams Ruby は、たとえば = を介して明示的にデフォルトよりも値に影響を与える場合を除いて、要素を「可視」としてタグ付けしません。
hash = Hash.new(Hash.new([]))
hash[1] = Hash.new([])
hash[1][2] = [3]
hash
#=> {1=>{2=>[3]}}
一部のセッターには、この「デフォルト設定を解除する」動作が欠けている可能性があります ...