Forum: Ruby barenames and case statements

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Eric W. (Guest)
on 2009-04-07 19:16
(Received via mailing list)
I've encountered this in the past and thought I was messing something
up, but it's happening still.

Can anyone tell me why this:

puts "ruby-#{RUBY_VERSION} [#{RUBY_PLATFORM}]"

[String, Array, Hash].each do |klass|
    case klass
    when String
        puts "String!"
    when Array
        puts "Array!"
    when Hash
        puts "Hash!"
    else
        puts "I don't know: #{klass}"
    end
end

Produces this:

ruby-1.8.7 [x86_64-linux]
I don't know: String
I don't know: Array
I don't know: Hash

ruby-1.9.1 [x86_64-linux]
I don't know: String
I don't know: Array
I don't know: Hash

Am I missing something here? In order to get the expected result I
have to do this:

[String, Array, Hash].each do |klass|
    case klass.to_s
    when "String"
        puts "String!"
    when "Array"
        puts "Array!"
    when "Hash"
        puts "Hash!"
    else
        puts "I don't know: #{klass}"
    end
end

This works of course, but why doesn't the former? I find it hard to
believe this has been overlooked. What am I missing?

-- Eric W.
LAMBEAU Bernard (Guest)
on 2009-04-07 19:22
(Received via mailing list)
Because the === operator of the Class class (used in case statements)
checks for 'is an instance of'.

So, the following:

>    case klass
>    when String
>        puts "String!"
>    end

is to be interpreted as String===klass, that is to,
klass.is_a?(String), which is false. But the following is true:

case klass
when Class
  puts 'It's a class of course'
end

Hope it helps
blambeau
Robert K. (Guest)
on 2009-04-07 20:05
(Received via mailing list)
On 07.04.2009 17:21, LAMBEAU Bernard wrote:
> is to be interpreted as String===klass, that is to,
> klass.is_a?(String), which is false. But the following is true:
>
> case klass
> when Class
>   puts 'It's a class of course'
> end

A solution would be to use the other form of "case":

[String, Array, Hash].each do |klass|
     case
     when klass == String
         puts "String!"
     when klass == Array
         puts "Array!"
     when klass == Hash
         puts "Hash!"
     else
         puts "I don't know: #{klass}"
     end
end

Or encapsulate tests in a special instance:

IsString = Object.new
def IsString.===(c)
   String == c
end

klass = String

case klass
when IsString
   puts "Ah!"
end


Kind regards

  robert
Eric W. (Guest)
on 2009-04-07 20:27
(Received via mailing list)
On Tue, Apr 7, 2009 at 11:21 AM, LAMBEAU Bernard 
<removed_email_address@domain.invalid>
wrote:
> Because the === operator of the Class class (used in case statements)
> checks for 'is an instance of'.

I understand. Definitely not what I'd expect. So my .to_s is the only
way to reasonably accomplish what I need to do? Overriding these
things would probably not be a good idea.

> Hope it helps
> blambeau

Thanks,

-- Eric W.
Eric W. (Guest)
on 2009-04-07 20:45
(Received via mailing list)
On Tue, Apr 7, 2009 at 12:04 PM, Robert K.
<removed_email_address@domain.invalid> wrote:

> A solution would be to use the other form of "case":
> Or encapsulate tests in a special instance:

I think the .to_s works just as well, but thanks.

> Kind regards
>
>        robert

-- Eric W.
botp (Guest)
on 2009-04-07 20:53
(Received via mailing list)
On Wed, Apr 8, 2009 at 12:43 AM, Eric W. <removed_email_address@domain.invalid> 
wrote:
> I think the .to_s works just as well, but thanks.

try also,
    case klass.new
         when String
    ...
The H. (Guest)
on 2009-04-07 22:06
class Object
  def singleton_class
    class << self
      self
    end
  end
end

[String, Array, Hash].each do |klass|
    case klass
    when String.singleton_class
        puts "String!"
    when Array.singleton_class
        puts "Array!"
    when Hash.singleton_class
        puts "Hash!"
    else
        puts "I don't know: #{klass}"
    end
end

Hrm it would be nice to have some kind of voting system for feature
requests
http://redmine.ruby-lang.org/issues/show/1082
This topic is locked and can not be replied to.