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?
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
···
On Tue, Apr 7, 2009 at 5:10 PM, Eric Will <rakaur@malkier.net> wrote:
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?
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
···
On 07.04.2009 17:21, LAMBEAU Bernard wrote:
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
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
···
On Tue, Apr 7, 2009 at 11:21 AM, LAMBEAU Bernard <blambeau@gmail.com> wrote:
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