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

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

所以这就是我做的:

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

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

这是预期的行为吗? 这里发生了什么?

顺便说一下,这是Ruby 1.9.1,还没有尝试过早期版本。

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

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

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

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

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

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