2012-05-01 22 views
7

Tengo un pedazo de código como este:error de hash Ruby: método no definido []

my_hash = {} 
first_key = 1 
second_key = 2 
third_key = 3 
my_hash[first_key][second_key][third_key] = 100 

y el intérprete de Ruby me dio un error dice que:

undefined method `[]' for nil:NilClass (NoMethodError)

¿Significa que no puede usar hash así? ¿o crees que este error podría deberse a otra cosa?

+0

consejos sobre cómo depurar el código: http://stackoverflow.com/q/3955688/38765 –

+0

Allan, probablemente debería aceptar una de las respuestas, a menos que considere que su pregunta no fue respondida por completo. (Probablemente cualquiera de texasbruce o la mía, ya que te dijimos una manera de lograr lo que quieres. Aunque repito que no es necesariamente un buen estilo.) –

Respuesta

10

Los valores hash no están anidados por defecto. Como my_hash[first_key] no está configurado para nada, es nil. Y nil no es un hash, por lo que al intentar acceder a uno de sus elementos falla.

Así:

my_hash = {} 
first_key = 1 
second_key = 2 
third_key = 3 

my_hash[first_key] # nil 
my_hash[first_key][second_key] 
# undefined method `[]' for nil:NilClass (NoMethodError) 

my_hash[first_key] = {} 
my_hash[first_key][second_key] # nil 

my_hash[first_key][second_key] = {} 

my_hash[first_key][second_key][third_key] = 100 
my_hash[first_key][second_key][third_key] # 100 
+0

hola gracias, pero en realidad hice que mi hash sea estático ('@@ my_hash'), ¿los sub hashes también serán estáticos? ¿Entonces las sub_hashes no se inicializarán nuevamente si coloco este fragmento de código en un bucle? –

+5

@AllanJiang No existe tal cosa como "estático" en Ruby. –

2

No puede utilizar valores hash de esa manera; my_hash[first_key] es simplemente nulo, y luego la siguiente operación de indexación falla. Es posible hacer un objeto hash que se comporte de la manera que está buscando - vea http://t-a-w.blogspot.co.uk/2006/07/autovivification-in-ruby.html - pero no está claro que este sea un buen estilo.

+0

¡Gracias por la respuesta! Tengo otra pregunta más con esto, Por favor, eche un vistazo a mi comentario en la otra respuesta. Gracias –

7

La forma en que usa el hash no es válido en Ruby, porque cada valor debe asignarse primero a un hash antes de ir al hash anidado (supongo que era de PHP?), Pero puede usar el hash vivificado:

my_hash = Hash.new{|h,k| h[k]=Hash.new(&h.default_proc)} 
first_key = 1 
second_key = 2 
third_key = 3 
my_hash[first_key][second_key][third_key] = 100 
p my_hash 

#output: {1=>{2=>{3=>100}}} 

Esta es la forma en que puede sentirse cómodo.

+1

Bien, no sabía sobre 'default_proc'. –

+0

@AndrewMarshall Lo aprendí de otra persona también :) Considero que este uso es muy elegante. – texasbruce

0

Usted puede hacer algo como

class NilClass 

    def [] key 
    nil 
    end 

end 

en los inicializadores como nil_overrides.rb y usted será capaz de utilizar nil['xxx'].

Cuestiones relacionadas