Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

         

Ok, entonces quería crear un hash que tenga un hash vacío como valor predeterminado. Un poco raro, lo sé, pero digamos que pensé que podría ser útil.

Entonces, esto es lo que hice:

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

En otras palabras, no veo un miembro hash cuando inspecciono el hash, pero puedo acceder a él por su clave.

¿Es este comportamiento esperado? ¿Qué está pasando aquí?

Por cierto, este es Ruby 1.9.1, no he probado versiones anteriores.

Editar: ejemplo simplificado ya que no tiene que ser un hash de hash de hashes ...

¿Fue útil?

Solución

Es el comportamiento esperado (en todas las versiones de ruby). Y si experimentas un poco más, verás que siempre accedes al mismo hash, sin importar qué tecla uses:

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

La forma en que funciona Hash.new con un argumento predeterminado es: Si hace hash [key] , verifica si esa clave existe en el hash. Si lo hace, devuelve el valor de esa clave. Si no, devuelve el valor predeterminado. No agrega la clave al hash y devolverá el mismo objeto predeterminado (no una copia) cada vez.

Para obtener lo que desea, debe especificar un bloque predeterminado. De esa manera, el bloque se ejecutará cada vez que acceda a una clave que no esté en el hash. Dentro del bloque, puede crear un nuevo hash y establecer la clave en "punto". a ese hash. Me gusta así:

Hash.new { |h,k|  h[k] = {} }
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top