2009-10-30 17 views
6

Helo,Ruby: lista de diferentes propiedades entre objetos Obtener

Soy bastante nuevo en Rubí (usando 1.8.6) y necesito saber si la siguiente funcionalidad está disponible de forma automática y si no, lo cual sería la mejor método para implementarlo.

I have class Car. y tienen dos objetos:

car_a and car_b 

¿Hay alguna manera de que pudiera hacer un comparar y encontrar las propiedades que difieren en uno de los objetos en comparación con el otro?

Por ejemplo,

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' 

luego hacer un

car_a.compare_with(car_b) 

me debe dar:

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

o algo por el estilo?

Respuesta

5

necesita algunos ajustes, pero aquí está la idea básica:

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

¡Guau! ¡Esto es asombroso! ¡Lo intentaré! Gracias :) – saurabhj

0

No estoy seguro si es posible obtener la diferencia de propiedades de inmediato. Pero el trabajo sería probar el .eql? operador en ambos los objetos

#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 == 

Si hay una diferencia, entonces podría utilizar el método To_Array de la clase de objeto como

car_a.to_a 
car_b.to_a 

ahora comparando 2 arrays por diferencias sería fácil.

No se ha probado, pero

(car_a | car_b) - (car_a & car_b) 

o algo por el estilo le debería dar la diferencia en las propiedades.

HTH

+0

Clase # to_a no hace lo que quiere en absoluto. Básicamente devuelve una matriz que contiene el receptor (es decir, String.to_a == [String]). –

2

¿Qué tal

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

que tenía el mismo problema y estaba buscando a algunas de sus soluciones, pero Pensé que Ruby tenía que encontrar la manera de resolver esto. Descubrí ActiveModel :: Dirty. Funciona de maravilla.

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

+1

Sin embargo, esto es algo muy diferente de lo que el OP está pidiendo. –

+0

Estoy de acuerdo con Dave Newton. También ActiveModel es bastante pesado para un pensamiento tan simple ... – korCZis

Cuestiones relacionadas