case bug when comparing classes...?

T

Tim Becker

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]
 
V

Vincent Fourmond

Tim said:
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
 
T

Tim Becker

That would explain it :) Thanks!

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
 

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

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,818
Latest member
Brigette36

Latest Threads

Top