2010-07-09 8 views
5

Szukałem w pobliżu, ale nie mogę znaleźć żadnego wbudowanego sposobu konwersji obiektu (z mojego własnego dzieła) na mieszanie wartości, więc muszę szukać gdzie indziej .Konwersja obiektu do wartości mieszania w Ruby

Moja myśl polegała na użyciu .instance_variables, usunięciu @ z przodu każdej zmiennej, a następnie użyciu attr_accessor dla każdego z nich w celu utworzenia skrótu.

Co wy myślicie? Czy to jest "Droga Rubinowa", czy jest lepszy sposób na zrobienie tego?

+0

Jeżeli przypadkiem, stało się za pomocą szyn. '.attributes' pobierze to, co chcesz. –

+0

Możesz także użyć "haszysz" gem http://stackoverflow.com/a/17889367/960702 – mustafaturan

Odpowiedz

3

Zakładając wszystkie dane, które mają zostać włączone do mieszania jest przechowywane w zmiennych instancji:

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

W końcu poszedłem z prostszą wersją tego (bez mapy .map). – Dukeh

+0

@ Dukeh, czy mógłbyś dodać swoją prostszą wersję jako kolejną odpowiedź tutaj? – PlagueHammer

1

Nie znam natywnego sposobu, aby to zrobić, ale myślę, że twoja koncepcja polegająca na zwykłym powtarzaniu zmiennych instancji i tworzeniu skrótu jest właściwie drogą do zrobienia. Jest całkiem prosty.

Możesz użyć Object.instance_variables, aby uzyskać Tablicę wszystkich zmiennych instancji, które następnie przelecisz, aby uzyskać ich wartości.

+1

Uzgodnione i jeśli jest to coś, co musisz zrobić więcej niż raz, możesz po prostu rozszerzyć klasę o metodę to_hash. –

0

Czy potrzebujesz skrótu? lub czy potrzebujesz wygody używania skrótu?

Jeśli potrzebujesz sugestii Geoffa Lanotte w odpowiedzi Cody'ego Caughlana, to jest miłe. w przeciwnym razie możesz przeciążyć [] swoją klasę. coś jak.

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

lepsze wykorzystanie, <object>.attributes

będzie zwraca hash.

To o wiele bardziej czyste rozwiązanie.

Pozdrawiam!

1

Tylko ten działa

object.instance_values ​​