Posts Tagged ‘activerecord’

Ruby’s and Rails’ case gotcha when comparing classes

October 15th, 2008

While pairing yesterday I ran into quite an interesting problem when using the Ruby case statement. Now this should not come to a surprise because the case statement uses the === operator rather than the == operator (that is common in other languages). We were refactoring some code like this.


variable = group_class == Animal ? 8 : 2

initially this turned into


if group_class == Animal
  variable = 8
elsif group_class == Water
  variable = 2
else
  variable = nil
end

This code was simply meant to check against class type since group_class is holding the type of this object. We decided to change this into a case statement as we could see more group_class types coming down the road in the next iteration.


variable = case group_class
               when Animal: 3
               when Water: 8
               ....

So this code was assumingly supposed to work, however does not. Apparently the valid way of writing this class is to do:


variable = case group_class.name
               when "Animal": 3
               when "Water": 8
               ....

Then this code works as designed. Tracking down the reason for this is ActiveRecord’s overloaded == and === operators.


# File activerecord/lib/active_record/base.rb, line 1269
1269:       def ===(object)
1270:         object.is_a?(self)
1271:       end
-----
# File activerecord/lib/active_record/base.rb, line 2421
2421:       def ==(comparison_object)
2422:         comparison_object.equal?(self) ||
2423:           (comparison_object.instance_of?(self.class) &&
2424:             comparison_object.id == id &&
2425:             !comparison_object.new_record?)
2426:       end

Just a quirk I noticed. Enjoy :)

Tags: , , ,
Posted in Rails, Ruby | Comments (1)