For Float#class why is '===' different from '=='

Sorry, very newbie question …

C:/> ruby -v
ruby 1.8.2 (2004-12-25) [i386-mswin32]

C:/> irb
irb(main):001:0> a = 3.2
=> 3.2
irb(main):002:0> puts “match” if a.class==Float
match
=> nil
irb(main):003:0> puts “match” if a.class===Float
=> nil
irb(main):004:0>

Why does ‘==’ match, and ‘===’ does not. I am trying to use a case
statement on the class and it doesn’t work because ‘===’ is not giving
the newbie expected result.

Please don’t hurt me. Thanks for your patience! - RichB

The triple equals is a length of velvet rope, checking values much like
the double equals. The triple equals is the relationship operator for
Date.For example:

irb(main):001:0> year = 2005
=> 2005
irb(main):002:0> puts “included” if 2000…2006 === year
included
=> nil

On Aug 8, 2006, at 8:30 PM, richB wrote:

=> nil

No one wants to hurt you my friend, in fact ruby has anticipated your
need:

a = 2.3

case a
when Float

end
end

p Float === 1.2

Zikiss Chan wrote:

irb(main):001:0> year = 2005
=> 2005
irb(main):002:0> puts “included” if 2000…2006 === year
included
=> nil

Here’s the key:
irb(main):006:0> puts “too bad” if 2000…2004 == year
too bad
=> nil
irb(main):007:0> puts “not equal to the range” if 2000…2004 === year
not equal to the range
=> nil

I appreciate the responses. I’m still puzzled. It seems that “case a”
is different from “case a.class” and that the comparison being done by
“===” in when is influenced by the type/class of the when operand.

I guess I wasn’t expecting this. I am still trying to iron out my
conceptual understanding. Is it that “case a” is asking about the
object a, whereas
“case a.class” is asking about the object/attribute a.class. Clearly a
is Float but a.class is something else that evaluates to Float?

irb(main):001:0> a=2.3
=> 2.3
irb(main):002:0> case a.class
irb(main):003:1> when Float then puts “match”
irb(main):004:1> end
=> nil

irb(main):005:0> a=2.3
=> 2.3
irb(main):006:0> case a
irb(main):007:1> when Float then puts “match”
irb(main):008:1> end
match
=> nil

irb(main):009:0> a.class
=> Float

irb(main):010:0> case a
irb(main):011:1> when 2.3 then puts “match”
irb(main):012:1> end
match
=> nil

Thanks!

richB wrote:

I appreciate the responses. I’m still puzzled. It seems that “case a”
is different from “case a.class” and that the comparison being done by
“===” in when is influenced by the type/class of the when operand.

Like most operators, === is just a method call. The following are
equivalent:
case a
when b
and
if b === a

Therefore the behavior of === depends on b. If b is a Class (e.g.
Float), it’s
equivalent to a.is_a?(b). If b is a Float (e.g. 2.3), it’s equivalent to
b == a.

I usually view the === operator as the inclusion operator:
b === a -> does b include a?

which brings me to… would there be any nasty side-effects to this?
class Object
def ===(other)
if respond_to?(:include)
self == other or include?(other)
else
self == other
end
end
end

Daniel

richB wrote:

I appreciate the responses. I’m still puzzled. It seems that “case a”
is different from “case a.class” and that the comparison being done by
“===” in when is influenced by the type/class of the when operand.

I guess I wasn’t expecting this. I am still trying to iron out my
conceptual understanding. Is it that “case a” is asking about the
object a, whereas
“case a.class” is asking about the object/attribute a.class. Clearly a
is Float but a.class is something else that evaluates to Float?

What I mean to say is “a.class” is something that indicates “a” is a
Float, but “a.class” is not itself a Float value.

richB wrote:

richB wrote:

I appreciate the responses. I’m still puzzled. It seems that “case a”
is different from “case a.class” and that the comparison being done by
“===” in when is influenced by the type/class of the when operand.

I guess I wasn’t expecting this. I am still trying to iron out my
conceptual understanding. Is it that “case a” is asking about the
object a, whereas
“case a.class” is asking about the object/attribute a.class. Clearly a
is Float but a.class is something else that evaluates to Float?

What I mean to say is “a.class” is something that indicates “a” is a
Float, but “a.class” is not itself a Float value.

Right. a.class is Float which is a constant. Float.class is Class.

The #=== operator which I call the ‘sorta’ operator usually indicates
some kind of a, er, kind-of, range or inclusion relationship. For
example with Ranges, #=== tests whether a value is within the range.

The most prominent use of #=== is the case expression which uses
it to compare for equality–or inclusion–instead of the more
traditional #==. This enables interesting usage of case.

A particular implementation, Class#===, is of interest to you:

a.class == Float # true
Float === a # true

ri Object#===

“richB” [email protected] writes:

I appreciate the responses. I’m still puzzled. It seems that “case a”
is different from “case a.class” and that the comparison being done by
“===” in when is influenced by the type/class of the when operand.

Yes. The best way I have of mentally modelling === is this:

lhs === rhs means “Does rhs match lhs?”, where the definition of
what matches depends of course on the nature of lhs.

When lhs is a class object, it makes sense to say that ‘match’ means
the same as ‘is_a?’. When lhs is a range, it makes sense to say that
‘match’ means the same as ‘includes?’. When lhs is a Regexp, ‘match’
already has a useful meaning.

richB <richard_a_brunner yahoo.com> writes:

Why does ‘==’ match, and ‘===’ does not. I am trying to use a case
statement on the class and it doesn’t work because ‘===’ is not giving
the newbie expected result.

As others have said, === is a function call

case a
when Float # Float === a
when 2005 # 2005 === a

2005 is a FixNum, and FixNum implements === the same as ==
Float is a Class (as you’ll see if you type Float.class), and Class
implements
=== basically like this as far as I can tell:

class Class
def ===(other)
other.kind_of? self
end
end

So, the reason you’re getting the result you’re getting is because a ===
b
doesn’t necessarily mean b === a - it depends on the classes of a and b

Gareth