How does the 'case' statement work with constants?
I am using Ruby 1.9.2 and Ruby on Rails 3.2.2. I have the following method:
# Note: The 'class_name' parameter is a constant; that is, it is a model class name.
def my_method(class_name)
case class_name
when Article then make_a_thing
when Comment then make_another_thing
when ... then ...
else raise("Wrong #{class_name}!")
end
end
I would like to understand why, in the case
statement above, it always runs the else
"part" when I execute method calls like my_method(Article)
, my_method(Comment)
and so on.
How can I solve the issue? Does someone have advice how to handle this?
This is because case
calls ===
, and ===
on Class (or specifically Module, which Class descends from) is implemented like so:
mod === obj
→ true
or false
Case Equality—Returns true
if obj
is an instance of mod
or one of mod
's descendants. Of limited use for modules, but can be used in case statements to classify objects by class.
This means that for any constant except Class
& Module
(eg Foo
), Foo === Foo
always returns false
. As a result, you always get the else
condition in your case
statement.
Instead just call case
with the object itself, instead of its class, or use if
statements.
Pass an object reference to the method, as in the background it uses the === operator, so these will fail. eg
obj = 'hello'
case obj.class
when String
print('It is a string')
when Fixnum
print('It is a number')
else
print('It is not a string')
end
This on the other hand, works fine:
obj = 'hello'
case obj # was case obj.class
when String
print('It is a string')
when Fixnum
print('It is a number')
else
print('It is not a string')
end
See a relevant answer to "How to write a switch statement in Ruby" https://stackoverflow.com/a/5694333/1092644
如果您只想比较名称的相等性,可以将to_s
添加到类常量中。
def my_method(class_name)
case class_name.to_s
when 'Article'
make_a_thing
when 'Comment'
make_another_thing
... ...
end
end
链接地址: http://www.djcxy.com/p/25646.html
上一篇: 如何更改散列键
下一篇: 'case'语句如何与常量一起工作?