我使用Ruby的case
语法设置一些基于self.class
的简单逻辑,如下所示:
case self.class
when FirstClass
do stuff....
when SecondClass
do other stuff...
end
我很快意识到这总是会返回nil.
经过仔细调查,我发现case
使用===
而不是==
来检查相等性。在我的终端中运行self.class == FirstClass
时,我按预期获得true
,但self.class === FirstClass
会返回false
。
查看ruby文档,我找到了===
的{{3}}:
Case Equality - 对于类Object,实际上与调用#==相同, 但通常被后代覆盖以提供有意义的 案例陈述中的语义。
那里的任何人都可以了解可能发生的事情吗?提前谢谢。
答案 0 :(得分:5)
线索在“通常被后代覆盖以在case语句中提供有意义的语义”,特别是Module
overrides it:
Case Equality - 如果 obj 是 mod 的实例或 mod 的后代之一,则返回
true
。模块的用途有限,但可以在case
语句中用于按类对对象进行分类。
因此,模块===
的行为与is_a?
方法非常相似(事实上它只是在MRI Ruby中调用相同的实现函数,rb_obj_is_kind_of
)。在您的示例中,它评估为false
,因为self.class
不是FirstClass
的实例。它可能只是Class
的一个实例。然而,仅self
可以是一个实例:
case self
when FirstClass
do stuff....
when SecondClass
do other stuff...
end
(虽然我认为你的设计可能不太正确,但测试一个对象的类通常是代码味道。相反,你可能应该在对象中有不同的方法实现。)