2012-05-01 17 views
7

Ho un pezzo di codice come questo:errore di hash di Ruby: metodo non definito []

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

e l'interprete ruby ​​mi ha dato un errore dice che:

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

Quindi cosa significa I non puoi usare hash come quello? o pensi che questo errore potrebbe a causa di qualcos'altro?

+0

Suggerimenti su come eseguire il debug del codice: http://stackoverflow.com/q/3955688/38765 –

+0

Allan, probabilmente dovresti accettare una delle risposte, a meno che tu ritenga che la tua domanda non abbia ricevuto una risposta completa. (Probabilmente o il texasbruce o il mio, dal momento che ti abbiamo detto un modo per ottenere quello che vuoi.Perché ripeto che non è necessariamente un buon stile.) –

risposta

10

Gli hash non sono nidificati per impostazione predefinita. Poiché my_hash[first_key] non è impostato su alcun valore, è nil. E nil non è un hash, quindi il tentativo di accedere a uno dei suoi elementi non riesce.

Quindi:

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

ciao grazie, ma in realtà ho reso il mio hash statico ('@@ my_hash'), così anche i sub hash saranno statici? Quindi i sub_hashes non verranno nuovamente inizializzati se inserisco questo pezzo di codice in un ciclo? –

+5

@AllanJiang Non c'è nulla di "statico" in Ruby. –

2

Non è possibile utilizzare gli hash del genere; my_hash[first_key] è appena nullo, quindi la successiva operazione di indicizzazione fallisce. È possibile creare un oggetto hash che si comporta nel modo che stai cercando - vedi http://t-a-w.blogspot.co.uk/2006/07/autovivification-in-ruby.html - ma non è chiaro che questo sia un buon stile.

+0

Grazie per la risposta! Ho un'altra domanda con questo, per favore dai un'occhiata al mio commento sotto l'altra risposta. Grazie –

7

Il modo in cui si utilizza l'hash non è valido in Ruby, poiché ogni singolo valore deve essere assegnato a un hash prima di passare all'hash nidificato (suppongo che tu fossi di PHP?), Ma puoi utilizzare l'hash vivificato:

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}}} 

Questo è il modo in cui ci si sente a proprio agio.

+1

Bello, non sapeva di default_proc'. –

+0

@AndrewMarshall L'ho imparato anche da qualcun altro :) Considero questo utilizzo molto elegante. – texasbruce

0

Si può fare qualcosa di simile

class NilClass 

    def [] key 
    nil 
    end 

end 

negli inizializzatori come nil_overrides.rb e sarete in grado di utilizzare nil['xxx'].

Problemi correlati