2010-07-09 11 views
5

Ho cercato in giro, ma non riesco a trovare alcun modo incorporato per convertire un oggetto (della mia creazione) in un hash di valori, quindi deve essere necessario cercare altrove .Conversione di un oggetto in un hash di valori in Ruby

Il mio pensiero era quello di utilizzare .instance_variables, rimuovere lo @ dalla parte anteriore di ogni variabile, quindi utilizzare lo attr_accessor per ciascuno per creare l'hash.

Cosa ne pensate? È la "Via del Rubino", o c'è un modo migliore per farlo?

+0

Se, per caso, vi capita di utilizzare Rails. '.attributes' prenderà ciò che vuoi. –

+0

Puoi anche utilizzare la gemma "hashable" http://stackoverflow.com/a/17889367/960702 – mustafaturan

risposta

3

Supponendo che tutti i dati che si desidera essere incluso nella hash viene memorizzato in variabili di istanza:

class Foo 
    attr_writer :a, :b, :c 

    def to_hash 
    Hash[*instance_variables.map { |v| 
     [v.to_sym, instance_variable_get(v)] 
    }.flatten] 
    end 
end 

foo = Foo.new 
foo.a = 1 
foo.b = "Test" 
foo.c = Time.now 
foo.to_hash 
=> {:b=>"Test", :a=>1, :c=>Fri Jul 09 14:51:47 0200 2010} 
+0

Alla fine sono andato con una versione più semplice di questo (senza .map). – Dukeh

+0

@Dukeh, potresti aggiungere la tua versione più semplice come un'altra risposta qui? – PlagueHammer

1

Non conosco un modo nativo per farlo, ma penso che la tua idea di basare semplicemente l'iterazione su tutte le variabili di istanza e di costruire un hash sia fondamentalmente la strada da percorrere. È piuttosto diretto.

È possibile utilizzare Object.instance_variables per ottenere una matrice di tutte le variabili di istanza che verranno quindi ripetute su per ottenere i relativi valori.

+1

concordata e se è qualcosa che devi fare più di una volta, puoi semplicemente estendere la classe con un metodo to_hash. –

0

hai bisogno di un hash? o ti serve solo la comodità di usare un hash?

se avete bisogno di un suggerimento di Geoff Lanotte nella risposta di Cody Caughlan è bello. altrimenti potresti sovraccaricare [] per la tua classe. qualcosa di simile a.

class Test 
    def initialize v1, v2, v3 
     @a = x 
     @b = y 
     @c = z 
    end 

    def [] x 
     instance_variable_get("@" + x) 
    end 
end 

n = Test.new(1, 2, 3) 
p n[:b] 
-1

Migliore utilizzo, <object>.attributes

lo farà restituisce un hash.

È una soluzione molto più pulita.

Cheers!

1

Proprio questo funziona

object.instance_values ​​

Problemi correlati