Comparing Objects With Many Attributes

If you’re implementing your own == method for a complex class you sometimes end up with code that looks like this

1 def ==( other )
2   self.attribute_1 == other.attribute_1 &&
3   self.attribute_2 == other.attribute_2 &&
4   self.attribute_3 == other.attribute_3 &&
5   # Code snipped for brevity
6   self.attribute_19 == other.attribute_19 &&
7   self.attribute_20 == other.attribute_20
8 end

If you’re not paying attention you could end up comparing the wrong attributes or comparing two attributes of the same object or even the same attribute with itself. Similarily leaving out a && can cause all code before that point to be ignored. Using some of the built in features of Ruby and it’s core API we can almost eliminate this as well as make the code easier to read and maintain.

Firstly, thanks to Array#==

1 [ self.attribute_1, self.attribute_2 ] == [ other.attribute_1, other.attribute_2 ]

is equivalent to

1 self.attribute_1 == other.attribute_1 && self.attribute_2 == other.attribute_2

If we combine that with the fact that we can return values from a lambda, the first code listing at the top can be rewritten as

1 def ==( other )
2   attribute_values_of = lambda{ |object| [ object.attribute_1,
3                                            object.attribute_2,
4                                            # Code snipped for brevity
5                                            object.attribute_20 ]}
6   attribute_values_of[ self ] == attribute_values_of[ other ]
7 end

By setting the attribute values that are returned in a lambda that is applied to both objects in the comparison you can ensure that all attributes are correctly compared. Adding new attributes to the comparison entails merely adding them into the returned array.


Farrel Lifson is a lead developer at Aimred.

About Aimred

Aimred is a specialist Ruby and Ruby on Rails development house and consultancy based in Cape Town, South Africa.

We provide Ruby and Ruby on Rails development, consulting and training services to businesses and organisations of all sizes. If you want to find out how we can help you, contact us at info@aimred.com.

Recent Posts

Yearly Archives