Ruby: get a list of various properties of objects

Helo

I am new to Ruby (using 1.8.6) and should know if the following functions are available automatically, and if not, then this is the best way to implement it.

I have a Car class. And they have two objects:

car_a and car_b 

Is there any way to compare and find which properties differ in one of the objects compared to the other?

For example,

 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' 

then do

 car_a.compare_with(car_b) 

should give me:

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

or something like that?

+6
ruby introspection
source share
4 answers

needs some tweaking, but here's the basic 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) 
+5
source share

What about

 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} 
+2
source share

Not sure if you immediately get a difference in properties. But would work around try .eql? operator on both objects

 #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 the same as == 

If there is a difference, you can use the Object Object To_Array method, for example

 car_a.to_a car_b.to_a 

now comparing 2 arrays for a difference would be easy.

Not verified but

 (car_a | car_b ) - ( car_a & car_b ) 

or something similar should give you a difference in properties.

NTN

0
source share

I had the same problem and looked at some of your solutions, but I decided that Ruby should have solved this issue. I discovered ActiveModel :: Dirty. It works like a charm.

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

0
source share

All Articles