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]}}
可能是一些设置者缺少这种“非默认”行为......