2012-01-19 5 views
13

Sono a conoscenza di questa funzionalità fornita da ActiveSupport.Come posso ottenere l'accesso hash di stile JavaScript?

h = ActiveSupport::OrderedOptions.new 
h.boy = 'John' 
h.girl = 'Mary' 
h.boy # => 'John' 
h.girl # => 'Mary' 

Comunque ho già una grande hash e voglio accedere a tale hash usando la notazione punto. Questo è quello che ho provato:

large_hash = {boy: 'John', girl: 'Mary'} 
h = ActiveSupport::OrderedOptions.new(large_hash) 
h.boy # => nil 

Che non ha funzionato. Come posso fare questo lavoro.

Sto usando rubino 1.9.2

Aggiornamento:

dispiace Avrei detto che non posso usare openstruct perché non ha each_pair metodo che ha Struct. Non conosco le chiavi in ​​anticipo, quindi non posso usare openstruct.

+0

Quasi un'interrogazione identica: http://stackoverflow.com/questions/2240535/ruby-hash-keys-as-methods-on-a-class –

+0

possibile duplicato del [Rubino - chiavi hash ai nomi dei metodi?] (http://stackoverflow.com/questions/6423484/ru by-hash-keys-to-method-names) –

risposta

9

OpenStruct dovrebbe funzionare bene per questo.

Se volete vedere come funziona, o magari fare una versione personalizzata, iniziare con qualcosa di simile:

h = { 'boy' => 'John', 'girl' => 'Mary' } 

class << h 
    def method_missing m 
    self[m.to_s] 
    end 
end 

puts h.nothing 
puts h.boy 
puts h.girl 
6

Siete alla ricerca di OpenStruct

$ require 'ostruct' 
$ large_hash_obj = OpenStruct.new large_hash 
$ large_hash_obj.boy 
=> "John" 
+0

Spiacente, avrei dovuto dire che non posso usare openstruct perché non ha il metodo each_pair che ha Struct. Non conosco le chiavi in ​​mano quindi non posso usare openstruct. –

4

I created my own gem for this, e ho usato in tutti i miei progetti. Sembra proprio quello di cui hai bisogno:

large_hash = { boy: 'John', girl: 'Mary' } 
r = Ribbon.wrap large_hash 

r.boy 
=> "John" 

r.girl 
=> "Mary" 

r.keys 
=> [:boy, :girl] 

r.each_pair { |key, value| puts "#{key} => #{value}" } 
boy => John 
girl => Mary 

Mi piacerebbe un po 'di feedback.

3

Se è solo un piccolo script è sicuro di estendere Hash

class Hash 
    def method_missing sym,* 
    fetch(sym){fetch(sym.to_s){super}} 
    end 
end 

method_missing è un metodo magico che viene chiamato ogni volta che il codice tenta di chiamare un metodo che non esiste. Ruby intercetterà la chiamata fallita in fase di esecuzione e ti permetterà di gestirla in modo che il tuo programma possa recuperare con garbo. L'implementazione sopra tenta di accedere all'hash utilizzando il nome del metodo come simbolo, utilizzando il nome del metodo come stringa e alla fine non riesce con l'errore mancante del metodo integrato di Ruby.

Per un'applicazione più complessa, in cui l'aggiunta di questo comportamento per tutti gli hash potrebbe rompersi altro codice o third0party gemme, utilizzare un modulo ed estendere ogni istanza

module H 
    def method_missing sym,* 
    fetch(sym){fetch(sym.to_s){super}} 
    end 
end 

the = { answer: 42 } 
the.extend(H) 
the.answer # => 42 

e per una maggiore comodità si può anche propagare il modulo verso il basso di hash nidificate

module H 
    def method_missing sym,* 
    r = fetch(sym){fetch(sym.to_s){super}} 
    Hash === r ? r.extend(H) : r 
    end 
end 

the = { answer: { is: 42 } } 
the.extend(H) 
the.answer.is # => 42 
Problemi correlati