当我没想到这件事时,我很好奇:
var = "foo"
case var.class
when String
puts "bar"
else
puts "baz"
=> "baz"
我理解案例陈述正在使用===
,但我不了解===
的作用。文档说......
Case Equality - 对于类Object,实际上与调用#==相同, 但通常被后代覆盖以提供有意义的 案例陈述中的语义。
http://ruby-doc.org/core-2.2.3/Object.html#method-i-3D-3D-3D
这是否意味着Class(或其中一个模块)中的===
会覆盖Object中的===
?我很困惑。
答案 0 :(得分:5)
===
被Class
个对象覆盖(更常见的是,Module
objects)表示"右侧是左侧的一个实例&#34 ;
例如:
>> String === ""
=> true
>> Class === String
=> true
这是不直观的,但这是真的。但是,它确实会让您尝试做的更短:
var = "foo"
case var
when String
puts "bar"
else
puts "baz"
end
# outputs "bar", since String === "foo"
这就是为什么你的尝试没有成功的原因:Ruby评估String === String
,这是错误的,因为String
类本身不是一个字符串。
答案 1 :(得分:2)
您在这里正在处理case equality
。在这里,它被后代覆盖以提供有意义的语义。在这种情况下,Module
会覆盖它。
Case Equality - 如果对象是模块的实例或模块的后代之一,则返回true。模块的用途有限,但可以在case语句中用于按类对对象进行分类。
在模块中,===
的行为类似于Ruby的is_a?
方法。
在您的情况下,它返回false,因为"Foo".class
不是字符串类的实例。
"Foo".class.is_a?(String)
=> false
答案 2 :(得分:1)
它与如何为类实现大小写等价运算符===
有关。使用对象,而不是object.class
var = "foo"
case var
when String
puts "bar"
else
puts "baz"
=> "bar"