2010-07-09 34 views
5

He buscado, pero no encuentro ninguna forma integrada de convertir un objeto (de mi propia creación) en un hash de valores, por lo que debo buscar en otra parte .Convirtiendo un objeto a un hash de valores en Ruby

Mi idea era utilizar .instance_variables, despojar a la @ desde la parte frontal de cada variable, y luego usar el attr_accessor para cada uno para crear el hash.

¿Qué piensan? ¿Es ese el 'Ruby Way', o hay una mejor manera de hacerlo?

+0

Si, por ventura, que se esté utilizando rieles. '.attributes' captará lo que quieras. –

+0

También puede usar la gema 'hashable' http://stackoverflow.com/a/17889367/960702 – mustafaturan

Respuesta

3

Suponiendo que todos los datos que desea ser incluido en el hash se almacena en las variables de instancia:

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

Al final fui con una versión más simple de esto (sin el .map). – Dukeh

+0

@Dukeh, ¿podría agregar su versión más simple como otra respuesta aquí? – PlagueHammer

1

No conozco una forma nativa de hacer esto, pero creo que su idea de básicamente iterar sobre todas las variables de instancia y crear un hash es básicamente el camino a seguir. Es bastante directo.

Puede usar Object.instance_variables para obtener una matriz de todas las variables de instancia que luego recorre para obtener sus valores.

+1

de acuerdo y si es algo que necesita hacer más de una vez, puede simplemente extender Class con un método to_hash. –

0

¿necesitas un hash? ¿o solo necesitas la conveniencia de usar un hash?

si necesita una tiene la sugerencia de Geoff Lanotte en Cody La respuesta de Caughlan es agradable. de lo contrario, podrías sobrecargar [] para tu clase. algo como.

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

Mejor uso, <object>.attributes

que se devuelve una hash.

Es una solución mucho más limpia.

¡Salud!

1

Sólo esto funciona

object.instance_values ​​

Cuestiones relacionadas