What on earth

a = 5
puts Fixnum == a.class # spits out true

# spits out "Who knows what I am. :-("
case a.class
when Fixnum
  puts "I'm a fixnum!"
else
  puts "Who knows what I am. :-("
end

What's going on here?

Joe

Joe Van Dyk wrote:

a = 5
puts Fixnum == a.class # spits out true

# spits out "Who knows what I am. :-("
case a.class
when Fixnum
  puts "I'm a fixnum!"
else
  puts "Who knows what I am. :-("
end

What's going on here?

Joe

I'll admit I only started learning Ruby 3 days ago, so don't hold it
against me if I misguide you ;), but I believe switch uses '===' to
compare, which I think is a more precise match...

5.class == Fixnum => true
5.class === Fuxnum => false

You might want to just use ifs instead.

Burke

case uses === for comparison, not ==

In my irb, Fixnum === 5.class => false

As for why === gives false, I have no idea. In the mean time, you could use

case a.class.to_s
when "Fixnum"
    puts ....
else
   puts ....
end

Tim

···

On Mar 22, 2006, at 6:51 PM, Joe Van Dyk wrote:

a = 5
puts Fixnum == a.class # spits out true

# spits out "Who knows what I am. :-("
case a.class
when Fixnum
  puts "I'm a fixnum!"
else
  puts "Who knows what I am. :-("
end

What's going on here?

Joe

case doesn't use == you can do this:

a = 5

case a
when Fixnum
   puts "I'm a fixnum"
else
   puts "other"
end

and by coincidence (not)

ratdog:~/tmp mike$ irb
irb(main):001:0> a = 5
=> 5
irb(main):002:0> Fixnum === a
=> true

ratdog:~/tmp mike$ ri Module#===
------------------------------------------------------------- Module#===
      mod === obj => true or false

···

On 22-Mar-06, at 9:51 PM, Joe Van Dyk wrote:

a = 5
puts Fixnum == a.class # spits out true

# spits out "Who knows what I am. :-("
case a.class
when Fixnum
  puts "I'm a fixnum!"
else
  puts "Who knows what I am. :-("
end

What's going on here?

------------------------------------------------------------------------
      Case Equality---Returns +true+ if _anObject_ is an instance of
      _mod_ or one of _mod_'s descendents. Of limited use for modules,
      but can be used in +case+ statements to classify objects by class.

Hope this helps,

Mike

--

Mike Stok <mike@stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.

burke wrote:

5.class === Fuxnum => false

Umm, ok. Obviously it's not a Fuxnum. I think I should clear that up:

5.class === Fixnum => false
as well. haha... Sorry about that.

Burke

case doesn't use == you can do this:

a = 5

case a
when Fixnum
  puts "I'm a fixnum"
else
  puts "other"
end

ratdog:~/tmp mike$ ri Module#===
------------------------------------------------------------- Module#===
     mod === obj => true or false
------------------------------------------------------------------------
     Case Equality---Returns +true+ if _anObject_ is an instance of
     _mod_ or one of _mod_'s descendents. Of limited use for modules,
     but can be used in +case+ statements to classify objects by class.

Ok, out of the three of us that responded, Mike is the one who knows what he's talking about most. Listen to him.

Tim

Very nice, thanks! Less code is always better.

···

On 3/22/06, Mike Stok <mike@stok.ca> wrote:

On 22-Mar-06, at 9:51 PM, Joe Van Dyk wrote:

> a = 5
> puts Fixnum == a.class # spits out true
>
> # spits out "Who knows what I am. :-("
> case a.class
> when Fixnum
> puts "I'm a fixnum!"
> else
> puts "Who knows what I am. :-("
> end
>
>
> What's going on here?

case doesn't use == you can do this:

a = 5

case a
when Fixnum
   puts "I'm a fixnum"
else
   puts "other"
end

Hi --

Joe Van Dyk wrote:

a = 5
puts Fixnum == a.class # spits out true

# spits out "Who knows what I am. :-("
case a.class
when Fixnum
  puts "I'm a fixnum!"
else
  puts "Who knows what I am. :-("
end

What's going on here?

Joe

I'll admit I only started learning Ruby 3 days ago, so don't hold it
against me if I misguide you ;), but I believe switch uses '===' to
compare, which I think is a more precise match...

5.class == Fixnum => true
5.class === Fixnum => false

(I've fixed your Fux :slight_smile:

It's not that it's more precise; it's just different. For classes,
=== is defined so that:

   X === x

is true if X is the class of x or one of that class's ancestors. The
idea is to make it easy to do:

   case obj
   when X ...
   when Y ...

But when obj is itself a class, you'll only get a positive if you test
to see whether it's a Class object:

   case 5.class
   when Class # this will be true

David

···

On Thu, 23 Mar 2006, burke wrote:

--
David A. Black (dblack@wobblini.net)
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

"Ruby for Rails" chapters now available
from Manning Early Access Program! Ruby for Rails

Ok, this is off the original track of discussion a bit, but I wanted to bring this up.

irb(main):007:0> 5 === Fixnum
=> false
irb(main):008:0> Fixnum === 5
=> true

irb(main):001:0> 5.class === Class
=> false
irb(main):002:0> Class === 5.class
=> true

I understand why this is happening (I think). I just think this needs to be fixed. Or is there a reason why === should not be commutative?

Tim

I think of it more as a relationship which has "direction", so in my view there's nothing to be fixed. In the class comparison it's testing whether the class of the operand is the same as _or an ancestor of_ the receiver. So it's not plain same as. (wording taken from the Pickaxe book)

Mike

···

On 22-Mar-06, at 10:44 PM, Timothy Bennett wrote:

Ok, this is off the original track of discussion a bit, but I wanted to bring this up.

irb(main):007:0> 5 === Fixnum
=> false
irb(main):008:0> Fixnum === 5
=> true

irb(main):001:0> 5.class === Class
=> false
irb(main):002:0> Class === 5.class
=> true

I understand why this is happening (I think). I just think this needs to be fixed. Or is there a reason why === should not be commutative?

--

Mike Stok <mike@stok.ca>
http://www.stok.ca/~mike/

The "`Stok' disclaimers" apply.

For the cases you give, it seems pretty straightforward, but what about this:

Fixnum===Class #false
Class===Fixnum #true

Should Class be considered a Fixnum just because Fixnum is a Class?

···

On 3/22/06, Timothy Bennett <timothy.s.bennett@gmail.com> wrote:

Ok, this is off the original track of discussion a bit, but I wanted
to bring this up.

irb(main):007:0> 5 === Fixnum
=> false
irb(main):008:0> Fixnum === 5
=> true

irb(main):001:0> 5.class === Class
=> false
irb(main):002:0> Class === 5.class
=> true

I understand why this is happening (I think). I just think this
needs to be fixed. Or is there a reason why === should not be
commutative?

Timothy Bennett wrote:

Ok, this is off the original track of discussion a bit, but I wanted to bring this up.

irb(main):007:0> 5 === Fixnum
=> false
irb(main):008:0> Fixnum === 5
=> true

irb(main):001:0> 5.class === Class
=> false
irb(main):002:0> Class === 5.class
=> true

So that was what got me a few weeks ago when using a case statement! I was like 'what the ?? is happening' It seems the === operator is an good example of bad overloading - it means something different to each class. Why not let "abc" === "ABC" while we're at it :wink:

Mike

···

I understand why this is happening (I think). I just think this needs to be fixed. Or is there a reason why === should not be commutative?

Tim

Hm, at least that makes sense. However, it's hard for me to think of === as having direction (it doesn't look like it has direction, and therefore it can be difficult to remember which direction it's supposed to go sometimes).

Though for some reason it's easier for me to accept that (1..5) === 3 gives true while 3 === (1..5) gives false. I'll have to remember it that way, and later I'll probably wince when I recall that 5 === Fixnum #=> false confused me (assuming that I'm able to recall this, which I probably won't as my memory is pretty bad. So some day in the future someone will say to me "This used to confuse you!" and show me this email and I shall suffer from horror and shock at evidence of my old ignorance.)

And no, that is not an invitation to approach me one day with this email in hand :slight_smile:

Tim

···

On Mar 22, 2006, at 8:22 PM, Caleb Clausen wrote:

For the cases you give, it seems pretty straightforward, but what about this:

Fixnum===Class #false
Class===Fixnum #true

Should Class be considered a Fixnum just because Fixnum is a Class?

Timothy Bennett wrote:

For the cases you give, it seems pretty straightforward, but what about this:

Fixnum===Class #false
Class===Fixnum #true

Should Class be considered a Fixnum just because Fixnum is a Class?

Hm, at least that makes sense. However, it's hard for me to think of === as having direction (it doesn't look like it has direction, and therefore it can be difficult to remember which direction it's supposed to go sometimes).

I drew some (a little) criticism for spending four pages
in _The Ruby Way_ covering the case statement.

I think it's powerful, and I think it's done the Right Way,
and shouldn't be changed.

But I also think there are some non-obvious quirks (such as
you describe).

It also bears remembering that === is not called on the item
being tested, but on each of the items tested against. So

   case x
     when a
       do_something
   end

means

   if a === x
     do_something
   end

HTH,
Hal

···

On Mar 22, 2006, at 8:22 PM, Caleb Clausen wrote:

Timothy Bennett schrieb:

Hm, at least that makes sense. However, it's hard for me to think of === as having direction (it doesn't look like it has direction, and therefore it can be difficult to remember which direction it's supposed to go sometimes).

After using it a couple of times, it's not that hard. I'm sure you have no problems with

   5 - 3

:wink:

Regards,
Pit

If four pages is what it takes.... I haven't read the Ruby Way yet (maybe if I had I wouldn't have been confused), but at the moment I wish that either Why's PG or the Pickaxe covered === a bit better. I also wish that it looked asymmetrical (maybe ==~ instead of ==, though that would invite people to think of it in relation to =~, which probably wouldn't be good either). Anyway, I think I'll be able to keep its role straight in my head.

Thanks for the help, guys.

Tim

···

On Mar 22, 2006, at 10:06 PM, Hal Fulton wrote:

Hm, at least that makes sense. However, it's hard for me to think of === as having direction (it doesn't look like it has direction, and therefore it can be difficult to remember which direction it's supposed to go sometimes).

I drew some (a little) criticism for spending four pages
in _The Ruby Way_ covering the case statement.

I think it's powerful, and I think it's done the Right Way,
and shouldn't be changed.

But I also think there are some non-obvious quirks (such as
you describe).

Timothy Bennett wrote:

... I also wish that it looked asymmetrical (maybe ==~ instead of ==,
though that would invite people to think of it in relation to =~, which
probably wouldn't be good either). Anyway, I think I'll be able to keep
its role straight in my head.

Actually there is a conceptual relationship between === and =~ - it is a
kind of matching. Regexp's === matches against strings, Range's === matches
things inside its range. As far as case and === is concerned, it helps me to
think of a class as something that matches instances in a similar way.

Cheers,
Dave