2012-05-28 13 views
24

Ho un progetto non-Rails in cui sto caricando alcune impostazioni da un file YAML:Hash con accesso indifferente

config = YAML::load(File.open("#{LOG_ROOT}/config/database.yml")) 

posso accedere solo questo hash come config["host"], config["username"] ecc

I voglio un accesso indifferente, così posso usare sia :host e "host".

Il motivo è che una delle gemme nel progetto a cui sto passando questo hash sembra accedervi usando i simboli e non funziona al momento.

Qual è il modo migliore per creare un hash con accesso indifferente in questo scenario?

+10

Anche se non si sta usando le rotaie v'è alcuna ragione per cui proprio non poteva 'require 'active_support/core_ext/hash/indifferent_access'', e non c'è la vostra soluzione? – Casper

+2

Non ho installato gem active_support e mi chiedevo se dovessi installarlo solo per ottenere questa funzione. – Josnidhin

+0

Se non si desidera, copiare/incollare il codice nel proprio hash con una classe di accesso indifferente. Non ho guardato la soluzione di Rails, ma ne ho già scritta una prima, non può essere più di 50 LOC. –

risposta

15

Facciamo l'hash config restituire il valore per la versione stringata del tasto:

config = {"host"=>"value1", "Username"=>"Tom"} 
config.default_proc = proc{|h, k| h.key?(k.to_s) ? h[k.to_s] : nil} 
p config[:host] #=> "value1" 

I default_proc viene eseguito ogni volta quando una chiave non si trova nella hash. Nota che questo è solo la metà dell'accesso indifferente: config["host"] risulterà in nullo se è presente la chiave :host. Se questo deve lavorare troppo:

config.default_proc = proc do |h, k| 
    case k 
    when String then sym = k.to_sym; h[sym] if h.key?(sym) 
    when Symbol then str = k.to_s; h[str] if h.key?(str) 
    end 
end 
+8

Funzionerà per l'accesso tramite '[]' ma non per cose come 'delete' dove dovrai fornire la versione corretta di la chiave. Solo per quello che ne sei a conoscenza – iain

+2

Nota anche che non impedirà a qualcuno di aggiungere due chiavi: "host" e: host con diversi valori assegnati! Se hai la chiave "host" nell'Hash e aggiungi la chiave: host il secondo non sovrascriverà th e il primo! – wrzasa

42

Non si perde nulla tranne alcuni KB di spazio su disco installando la gemma di Supporto attivo. Nel codice, si richiede solo la funzione che si desidera:

require 'active_support/core_ext/hash/indifferent_access' 

In questo modo, si può essere sicuri che non si ottiene niente altro per rovinare il vostro spazio dei nomi.

+1

Sì, ma poi cose come questa interruzione :(- "% {version}"% {versione: 5} .with_indifferent_access.to_hash perché sto indovinando internamente le stringhe usate al posto dei simboli :( –

+0

Osservazione interessante. io un trucco che non sapevo nemmeno io :-), e vedo che non funziona con quegli hash indifferenti di ActiveSupport. Con un breve preavviso, non sono in grado di dire se questo può essere risolto, ma tu faresti un buona azione per la comunità di Ruby se vuoi inviare un ticket a questo effetto agli sviluppatori di ActiveSupport. –

Problemi correlati