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, for a === b where 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.

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

So I was very suprised to find this:

1
2
3
4
5
6
7
8
>> 3.days.class
=> Fixnum

>> Fixnum === 3.days
=> False

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

1
2
3
def days
  ActiveSupport::Duration.new(self * 24.hours, [[:days, self]])
end

And, in fact:
1
2
  >> ActiveSupport::Duration === 3.days 
  => true

I'm not clear on why this happens. I'll update this post as it becomes clear.
  1. Anonymous's Gravatar Anonymous says:

    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.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.

Post a comment


(lesstile enabled - surround code blocks with ---)