Friday, May 29, 2009

1.day Ruby's case operator === behaved badly

This is a follow-up to a previous post about the Ruby case operator, ===.

I previously understood that given
    a === b
when a is a class, the result would be b.class.ancestors.include?(a)
when a is an instance, the result would be a == b

This proves true for many examples.

>> 3.class.ancestors.all? {|a| a === 3}
=> true

So I was very suprised to find this:

>> 3.days.class
=> Fixnum
>> Fixnum === 3.days
=> False
>> 3.days.class.ancestors.include?(Fixnum)
=> true

here's the method days:
def days   ActiveSupport::Duration.new(self * 24.hours, [[:days, self]]) end
And, in fact:
>> ActiveSupport::Duration === 3.days
=> true

I'm not clear on why this happens. I'll update this post as it becomes clear.

1 comments:

MyID.config.php said...

ActiveSupport::Duration is a proxy class for Fixnum. It defines some methods (like self.===) and the rest, it forwards (including #class). This doesn't strike me as an appropriate use of a proxy class and I don't see why it was done instead of subclassing Fixnum.