为什么Hash.new({})会隐藏哈希成员?

时间:2009-11-30 19:54:06

标签: ruby hash default

好的,所以我想创建一个空哈希作为默认值的哈希。我知道,有点奇怪,但是我想我觉得它可能有用。

所以这就是我所做的:

>> a = Hash.new({})
=> {}
>> a[:a][:b] = 5
=> 5
>> a
=> {}
>> a[:a]
=> {:b=>5}
>> a.keys
=> []
>> a.size
=> 0
>> a[:a].size
=> 1

换句话说,当我检查哈希时,我没有看到哈希成员,但我可以通过它的密钥访问它。

这是预期的行为吗?这是怎么回事?

BTW,这是Ruby 1.9.1,还没有尝试过早期版本。

编辑:简化示例,因为它不必是散列哈希的散列...

1 个答案:

答案 0 :(得分:17)

预期的行为(跨所有ruby版本)。如果你进一步实验,你会发现无论你使用哪个密钥,你总是访问相同的哈希值:

>> a[:a][:b] = 1
=> 1
>> a[:c][:d] = 2
=> 2
>> a[:d]
=> {:b=>1, :d=>2}

使用默认参数的Hash.new的工作方式是:如果执行hash[key],它会检查哈希中是否存在该密钥。如果是,则返回该键的值。如果不是,则返回默认值。它不会将键添加到哈希值,并且每次都会返回相同的默认对象(而不是副本)。

要获得所需内容,您需要指定默认块。这样,每次访问不在哈希中的密钥时,都会执行该块。在块中,您可以创建一个新的Hash并将键设置为“指向”该哈希。像这样:

Hash.new { |h,k|  h[k] = {} }