[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

case bug when comparing classes...?

Tim Becker

12/29/2006 10:50:00 AM

Hi,
I'm encountering weird behavior I don't understand when creating a
case expression that does comparison using classes. Consider the
following:

class SomeClass
end

def case_test elem
case elem.class
when Object
puts "Object"
when String
puts "String"
when SomeClass
puts "SomeClass"
else
puts "Unknown: #{elem.class}"
end
end

executing:

case_test Object.new
case_test "bla"
case_test SomeClass.new
case_test 1

yields:

Object
Object
Object
Object


On the other hand, running:

def if_test elem
if Object == elem.class
puts "Object"
elsif String == elem.class
puts "String"
elsif SomeClass == elem.class
puts "SomeClass"
else
puts "Unknown: #{elem.class}"
end
end

if_test Object.new
if_test "bla"
if_test SomeClass.new
if_test 1


results in:

Object
String
SomeClass
Unknown: Fixnum

I've not been able to find anything that fits searching the bug
database or doing a rudimentary google search, and it would seem to me
that someone else would have come across this before.

Am I missing something?

Thanks,
-tim

Oh and btw: ruby 1.8.5 (2006-08-25) [i686-darwin8.8.1]

2 Answers

Vincent Fourmond

12/29/2006 11:01:00 AM

0

Tim Becker wrote:
> Hi,
> I'm encountering weird behavior I don't understand when creating a
> case expression that does comparison using classes. Consider the
> following:
>
> class SomeClass
> end
>
> def case_test elem
> case elem.class
> when Object
> puts "Object"
> when String
> puts "String"
> when SomeClass
> puts "SomeClass"
> else
> puts "Unknown: #{elem.class}"
> end
> end
>
> executing:
>
> case_test Object.new
> case_test "bla"
> case_test SomeClass.new
> case_test 1
>
> yields:
>
> Object
> Object
> Object
> Object
>
>
> On the other hand, running:
>
> def if_test elem
> if Object == elem.class
> puts "Object"
> elsif String == elem.class
> puts "String"
> elsif SomeClass == elem.class
> puts "SomeClass"
> else
> puts "Unknown: #{elem.class}"
> end
> end
>
> if_test Object.new
> if_test "bla"
> if_test SomeClass.new
> if_test 1
>
>
> results in:
>
> Object
> String
> SomeClass
> Unknown: Fixnum
>
> I've not been able to find anything that fits searching the bug
> database or doing a rudimentary google search, and it would seem to me
> that someone else would have come across this before.
>
> Am I missing something?

Yes ;-).

Using the case construct implies that you're using the === operator.
And the === operator of a instance of Class is exactly is_a?. Which
means that, since elem.class is a instance of Class, it is an Object,
and your first test will always match.

You should try this:

def case_test elem
case elem
when String
puts "String"
when SomeClass
puts "SomeClass"
when Object
puts "Object"
else
puts "Unknown: #{elem.class}"
end
end

You need to put Object at the end, and look only at elem. (and you else
clause will never get executed)

Cheers,

Vince

--
Vincent Fourmond, PhD student
http://vincent.fourmon...

Tim Becker

12/29/2006 11:10:00 AM

0

That would explain it :) Thanks!

On 12/29/06, Vincent Fourmond <vincent.fourmond@9online.fr> wrote:
> Tim Becker wrote:
> > Hi,
> > I'm encountering weird behavior I don't understand when creating a
> > case expression that does comparison using classes. Consider the
> > following:
> >
> > class SomeClass
> > end
> >
> > def case_test elem
> > case elem.class
> > when Object
> > puts "Object"
> > when String
> > puts "String"
> > when SomeClass
> > puts "SomeClass"
> > else
> > puts "Unknown: #{elem.class}"
> > end
> > end
> >
> > executing:
> >
> > case_test Object.new
> > case_test "bla"
> > case_test SomeClass.new
> > case_test 1
> >
> > yields:
> >
> > Object
> > Object
> > Object
> > Object
> >
> >
> > On the other hand, running:
> >
> > def if_test elem
> > if Object == elem.class
> > puts "Object"
> > elsif String == elem.class
> > puts "String"
> > elsif SomeClass == elem.class
> > puts "SomeClass"
> > else
> > puts "Unknown: #{elem.class}"
> > end
> > end
> >
> > if_test Object.new
> > if_test "bla"
> > if_test SomeClass.new
> > if_test 1
> >
> >
> > results in:
> >
> > Object
> > String
> > SomeClass
> > Unknown: Fixnum
> >
> > I've not been able to find anything that fits searching the bug
> > database or doing a rudimentary google search, and it would seem to me
> > that someone else would have come across this before.
> >
> > Am I missing something?
>
> Yes ;-).
>
> Using the case construct implies that you're using the === operator.
> And the === operator of a instance of Class is exactly is_a?. Which
> means that, since elem.class is a instance of Class, it is an Object,
> and your first test will always match.
>
> You should try this:
>
> def case_test elem
> case elem
> when String
> puts "String"
> when SomeClass
> puts "SomeClass"
> when Object
> puts "Object"
> else
> puts "Unknown: #{elem.class}"
> end
> end
>
> You need to put Object at the end, and look only at elem. (and you else
> clause will never get executed)
>
> Cheers,
>
> Vince
>
> --
> Vincent Fourmond, PhD student
> http://vincent.fourmon...
>
>