Case bug when comparing classes...?

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

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]

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.fourmond.neuf.fr/

That would explain it :slight_smile: 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
>
> 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.fourmond.neuf.fr/