That's Module#===
and its intended behavior:
mod === obj → true or false
Case Equality—Returns
true
if anObject is an instance of mod or one of mod’s descendants. Of limited use for modules, but can be used incase
statements to classify objects by class.
It simply returns obj.kind_of? mod
:
Fixnum === Fixnum #=> false
Fixnum.kind_of? Fixnum #=> false
Class === Class #=> true
Class.kind_of? Class #=> true
String === "foo" #=> true
"foo".kind_of? String #=> true
3
is both, an Integer
and a Fixnum
because of its class hierarchy:
3.kind_of? Integer #=> true
3.kind_of? Fixnum #=> true
3.class.ancestors #=> [Fixnum, Integer, Numeric, Comparable, Object, Kernel, BasicObject]
Numeric
is not an Integer
, it's a Class
:
Numeric.kind_of? Integer #=> false
Numeric.kind_of? Class #=> true
But 3
, (2/3)
and 1.23
are all Numeric
:
3.kind_of? Numeric #=> true
Rational(2, 3).kind_of? Numeric #=> true
1.23.kind_of? Numeric #=> true
Bottom line: for case
statements, just use case obj
instead of case obj.class
.
Update
You are getting this error because 5.months
doesn't return an Integer
, but a ActiveSupport::Duration
:
Integer === 5.months #=> false
ActiveSupport::Duration === 5.months #=> true
Calling your method with 5.months.to_i
or adding ActiveSupport::Duration
to your classes should fix it.