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

R

richB

# 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
 
L

Logan Capaldo

# 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

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
 
Z

Zikiss Chan

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
 
Z

Zikiss Chan

Zikiss said:
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
 
R

richB

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!
 
R

richB

richB said:
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.
 
D

Daniel DeLorme

richB said:
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
 
E

Eero Saynatkari

richB said:
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#===
 
D

Daniel Martin

richB said:
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.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,781
Messages
2,569,615
Members
45,295
Latest member
EmilG1510

Latest Threads

Top