2009-10-30 18 views
6

Helo,Ruby: Pobierz listę różnych właściwości między obiektami

Jestem całkiem nowy, Ruby (przy użyciu 1.8.6), a trzeba wiedzieć, czy następujące funkcje są dostępne automatycznie, a jeśli nie, który byłby najlepszy metoda wdrożenia.

Mam samochód klasy. i mają dwa obiekty:

car_a and car_b 

Czy jest jakiś sposób mogę zrobić porównać i znaleźć jakie właściwości różnią się w jednym z obiektów w stosunku do drugiego?

Na przykład

car_a.color = 'Red' 
car_a.sun_roof = true 
car_a.wheels = 'Bridgestone' 

car_b.color = 'Blue' 
car_b.sun_roof = false 
car_b.wheels = 'Bridgestone' 

następnie robi

car_a.compare_with(car_b) 

powinien dać mi:

{:color => 'Blue', :sun_roof => 'false'} 

lub coś w tym rodzaju?

Odpowiedz

5

potrzebuje trochę skomplikowany, ale tu jest podstawowa idea:

module CompareIV 
    def compare(other) 
    h = {} 
    self.instance_variables.each do |iv| 
     print iv 
     a, b = self.instance_variable_get(iv), other.instance_variable_get(iv) 
     h[iv] = b if a != b 
    end 
    return h 
    end 
end 

class A 
    include CompareIV 
    attr_accessor :foo, :bar, :baz 

    def initialize(foo, bar, baz) 
    @foo = foo 
    @bar = bar 
    @baz = baz 
    end 
end 

a = A.new(foo = 1, bar = 2, baz = 3) 
b = A.new(foo = 1, bar = 3, baz = 4) 

p a.compare(b) 
+0

Wow! To jest niesamowite! Wypróbuj! Dzięki :) – saurabhj

0

Nie jestem pewien, czy uzyskanie różnicy właściwości jest możliwe od razu. Ale praca wokół będzie próbować .eql? Operator na obu obiektach

#for example, 

car_a.eql?(car_b) 

#could test whether car_a and car_b have the same color, sunroof and wheels 
#need to override this method in the Car class to be meaningful,otherwise it's the same as == 

Jeśli istnieje różnica następnie można użyć metody To_Array obiektu klasy niczym

car_a.to_a 
car_b.to_a 

teraz porównując 2 tablice dla różnicy byłoby łatwe.

nie testowano, ale

(car_a | car_b) - (car_a & car_b) 

czy coś takiego powinno dać Ci różnicę we właściwościach.

HTH

+0

Klasa # to_a nie robi w ogóle tego, czego chcesz. Zasadniczo zwraca tablicę zawierającą odbiornik (tj. String.to_a == [String]). –

2

Jak o

class Object 
    def instance_variables_compare(o) 
    Hash[*self.instance_variables.map {|v| 
     self.instance_variable_get(v)==o.instance_variable_get(v) ? [] : [v,o.instance_variable_get(v)]}.flatten] 
    end 
end 


>> car_a.instance_variables_compare(car_b) 
=> {"@color"=>"Blue", "@sun_roof"=>false} 
0

miałem ten sam problem i patrzy na niektóre z rozwiązań, ale Doszedłem do wniosku, że Ruby musi mieć sposób na rozwiązanie tego problemu. Odkryłem ActiveModel :: Dirty. Działa jak marzenie.

http://api.rubyonrails.org/classes/ActiveModel/Dirty.html#method-i-changes

+1

Jest to coś zupełnie innego niż to, o co prosi OP. –

+0

Zgadzam się z Davem Newtonem. Również ActiveModel jest dość ciężkim kalibrem dla tak prostego myślenia ... – korCZis

Powiązane problemy