Siguiendo la documentacion de Ruby:

h = Hash.new("Go Fish")
   h["a"] = 100
   h["b"] = 200
   h["a"]           #=> 100
   h["c"]           #=> "Go Fish"
   # The following alters the single default object
   h["c"].upcase!   #=> "GO FISH"
   h["d"]           #=> "GO FISH"
   h.keys           #=> ["a", "b"]


al vos hacer
h = Hash.new({})
haces que todas las keys de ese hash inexistentes apunten a un nuevo hash
vacio.
Cuando vos haces
h[1][1] = 1
Estas accediendo directamenter a ese hash por defecto, haciendo la posicion
que la posicion 1 de ese hash aputne a 1
Es decir, no creaste antes un nuevo objeto al cual apunte h[1].
Entonces todos apuntan al mismo objeto!

Quizas esto te ayude un poco para verlo:

irb(main):001:0> h = Hash.new({})
=> {}
irb(main):002:0> h[1]
=> {}
irb(main):003:0> h[1] = 'Hola'
=> "Hola"
irb(main):004:0> h[2]
=> {}
irb(main):005:0> h.keys
=> [1]
irb(main):006:0> h[2][1] = 2
=> 2
irb(main):007:0> h.keys
=> [1]
irb(main):008:0> h[1] = {1 => 1}
=> {1=>1}
irb(main):009:0> h.keys
=> [1]
irb(main):010:0> h[1].keys
=> [1]

Es decir, si vos queres que para cada key del hash, tenga _su_propio_ hash
al cual apunta, creo que deberias hacer algo del estilo:

 # While this creates a new default object each time
   h = Hash.new { |hash, key| hash[key] = "Go Fish: #{key}" }
   h["c"]           #=> "Go Fish: c"
   h["c"].upcase!   #=> "GO FISH: C"
   h["d"]           #=> "Go Fish: d"
   h.keys           #=> ["c", "d"]


(sacado de la documentacion de ruby)

Lo que en tu caso seria:

h = Hash.new { |hash, key| hash[key] = {} }


Espero haber sido de ayuda.

Saludos,
Esteban.




2008/12/6 Lucas Sallovitz <[EMAIL PROTECTED]>

> On Sat, Dec 6, 2008 at 4:14 PM, Nelson Fernandez <[EMAIL PROTECTED]>
> wrote:
> > Lo que esta sucediento es que estás manjando el Hash como si fuera un
> > Array multidimencional
> >
> > a = Hash.new('hola')
> > puts a[1] => 'hola'
> > puts a[1][1] => 108
> >
> > 108 es el ascii de la letra o
> >
>
> Gracias Nelson, pero no estoy seguro que sea el caso, en tu ejemplo
> a[1] es un string, por lo tanto el operador [] devuelve el caracter
> que está en la posición que indica el índice, pero en el mío, h[1] es
> un hash, por lo que el operador [] debería devolver el valor apuntado
> por el objeto que paso como índice, que como no existe debería ser en
> este caso: {}.
>
> Te paso otro ejemplo que tal vez muestre mejor lo que quiero decir:
>
> h = Hash.new({})
> h['a']['b'] = 'c'
> p h['a']                     =>  {"b"=>"c"}
> p h['a']['b']                =>  "c"
> p h['no existe']         =>  {"b"=>"c"}
>
> Cuando según la definición de hash, el tercer caso debería devolver
> {}, o eso es lo que yo interpreto.
>
> Saludos. Lucas.
> _______________________________________________
> Ruby mailing list
> [email protected]
> http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar
>
_______________________________________________
Ruby mailing list
[email protected]
http://lista.rubyargentina.com.ar/listinfo.cgi/ruby-rubyargentina.com.ar

Responder a