barenames and case statements

E

Eric Will

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 Will
 
L

LAMBEAU Bernard

Because the =3D=3D=3D 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=3D=3D=3Dklass, 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

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|
=A0 =A0case klass
=A0 =A0when String
=A0 =A0 =A0 =A0puts "String!"
=A0 =A0when Array
=A0 =A0 =A0 =A0puts "Array!"
=A0 =A0when Hash
=A0 =A0 =A0 =A0puts "Hash!"
=A0 =A0else
=A0 =A0 =A0 =A0puts "I don't know: #{klass}"
=A0 =A0end
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|
=A0 =A0case klass.to_s
=A0 =A0when "String"
=A0 =A0 =A0 =A0puts "String!"
=A0 =A0when "Array"
=A0 =A0 =A0 =A0puts "Array!"
=A0 =A0when "Hash"
=A0 =A0 =A0 =A0puts "Hash!"
=A0 =A0else
=A0 =A0 =A0 =A0puts "I don't know: #{klass}"
=A0 =A0end
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 Will
 
R

Robert Klemme

Because the === operator of the Class class (used in case statements)
checks for 'is an instance of'.

So, the following:


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
 
E

Eric Will

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 Will
 
T

The Higgs bozo

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
 

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

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top