Ruby class types and case statements
What is the difference between
case item.class
when MyClass
# do something here
when Array
# do something different here
when String
# do a third thing
end
and
case item.class
when MyClass.class
# do something here
when Array开发者_运维技巧.class
# do something different here
when String.class
# do a third thing
end
For some reason, the first one of these works sometimes and the second doesn't, and other times, the second one works and the first one doesn't. Why? Which one is the "proper" way to do it?
You must use:
case item
when MyClass
...
I had the same problem: How to catch Errno::ECONNRESET class in "case when"?
Yeah, Nakilon is correct, you must know how the threequal === operator works on the object given in the when
clause. In Ruby
case item
when MyClass
...
when Array
...
when String
...
is really
if MyClass === item
...
elsif Array === item
...
elsif String === item
...
Understand that case is calling a threequal method (MyClass.===(item)
for example), and that method can be defined to do whatever you want, and then you can use the case statement with precisionw
You can use:
case item.class.to_s
when 'MyClass'
...when the following twist is not possible:
case item
when MyClass
The reason for this is that case
uses ===
, and the relationship the ===
operator describes is not commutative. For example, 5
is an Integer
, but is Integer
a 5
? This is how you should think of case
/when
.
In Ruby, a class name is a constant that refers to an object of type Class
that describes a particular class. That means that saying MyClass
in Ruby is equivalent to saying MyClass.class
in Java.
obj.class
is an object of type Class
describing the class of obj
. If obj.class
is MyClass
, then obj
was created using MyClass.new
(roughly speaking). MyClass
is an object of type Class
that describes any object created using MyClass.new
.
MyClass.class
is the class of the MyClass
object (it's the class of the object of type Class
that describes any object created using MyClass.new
). In other words, MyClass.class == Class
.
It depends on the nature of your item
variable. If it is an instance of an object, e.g.
t = 5
then
t.class == Fixnum
but if it is a class in itself e.g
t = Array
then it will be a Class
object, so
t.class == Class
EDIT: please refer to How to catch Errno::ECONNRESET class in "case when"? as stated by Nakilon since my answer could be wrong.
精彩评论