我使用的是Ruby 1.9.2,Ruby在Rails 3.2.2上。我有以下方法:
# 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
我想了解为什么在上面的case
语句中,当我执行诸如my_method(Article)
,my_method(Comment)
等方法时,它总是运行else
" part"。
如何解决这个问题?有人有建议如何处理吗?
这是因为case
调用===
,而===
在类上(或专门的模块,class discends frocs so so:
mod === obj
→true
或false
案例平等 - 返回
true
如果obj
是mod
的实例或mod
的后代之一。模块的使用有限,但可以在语句中用来按类对象进行分类。
这意味着除了Class
&Module
(例如Foo
),Foo === Foo
始终返回false
。结果,您始终在case
语句中获得else
条件。
而不是将对象本身而不是类别调用case
,或者使用if
语句。
将对象引用传递到该方法,如背景中,它使用===操作员,因此这些将失败。例如
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
另一方面,工作正常:
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
请参阅"如何在Ruby中编写Switch语句"的相关答案。
如果您只想比较名称的平等,则可以将to_s
添加到类常数。
def my_method(class_name)
case class_name.to_s
when 'Article'
make_a_thing
when 'Comment'
make_another_thing
... ...
end
end