Por que Hash.new ({}) membros hide de hash? [duplicado]
Pergunta
Esta questão já tem uma resposta aqui:
Ok, então eu queria criar um hash que tem um hash vazio como o valor padrão. Um pouco estranho, eu sei, mas vamos dizer que eu pensei que poderia ser útil.
Então aqui está o que eu fiz:
>> a = Hash.new({})
=> {}
>> a[:a][:b] = 5
=> 5
>> a
=> {}
>> a[:a]
=> {:b=>5}
>> a.keys
=> []
>> a.size
=> 0
>> a[:a].size
=> 1
Em outras palavras, não vejo membro de hash quando eu inspecionar o hash, mas eu posso acessá-lo por sua chave.
É este o comportamento esperado? O que está acontecendo aqui?
BTW, este é o Ruby 1.9.1, não tentei versões anteriores.
Edit: exemplo simplificado uma vez que não tem que ser um hash de hashes de hashes ...
Solução
Espera-se um comportamento (em todas as versões de rubi). E se você experimentar um pouco mais, você vai ver que você sempre acessar o mesmo hash, não importa qual chave que você usa:
>> a[:a][:b] = 1
=> 1
>> a[:c][:d] = 2
=> 2
>> a[:d]
=> {:b=>1, :d=>2}
A forma Hash.new com um argumento padrão obras é: Se você fizer hash[key]
ele verifica se a chave existe no hash. Se isso acontecer, ele retorna o valor para essa chave. Se não devolve o valor padrão. Ele não adiciona a chave para o hash e ele irá retornar o mesmo objeto padrão (não uma cópia) de cada vez.
Para obter o que deseja, você quer especificar um bloco padrão em vez. Dessa forma, o bloco será executado toda vez que você acessar uma chave que não está no hash. Dentro do bloco que você pode criar uma nova Hash e definir a chave para o "point" para que hash. Como assim:
Hash.new { |h,k| h[k] = {} }