[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

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

richB

8/9/2006 12:28:00 AM

# 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

9 Answers

Logan Capaldo

8/9/2006 12:45:00 AM

0


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

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


Zikiss Chan

8/9/2006 1:12:00 AM

0

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

--
Posted via http://www.ruby-....

Zikiss Chan

8/9/2006 1:16:00 AM

0

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

--
Posted via http://www.ruby-....

richB

8/9/2006 2:44:00 AM

0

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

8/9/2006 2:49:00 AM

0


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.

Daniel DeLorme

8/9/2006 3:13:00 AM

0

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

e

8/9/2006 4:31:00 AM

0

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

--
Posted via http://www.ruby-....

Jeff Schwab

8/9/2006 1:02:00 PM

0

richB wrote:
> # 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.

Because Float is not an instance of class Float.

Good question.

Daniel Martin

8/9/2006 2:29:00 PM

0

"richB" <richard_a_brunner@yahoo.com> 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.