为什么 "foo".class === String return 为假?

Why does "foo".class === String return false?

当这没有像我预期的那样工作时,我开始好奇:

var = "foo"
case var.class
when String
  puts "bar"
else
  puts "baz"
=> "baz"

我知道 case 语句使用的是 ===,但我不明白 === 的作用。文档说...

Case Equality – For class Object, effectively the same as calling #==, but typically overridden by descendants to provide meaningful semantics in case statements.

http://ruby-doc.org/core-2.2.3/Object.html#method-i-3D-3D-3D

这是否意味着 Class(或其模块之一)中的 === 覆盖了 Object 中的 ===?我很困惑。

===Class 对象(更一般地说,Module objects)覆盖为 "is the right-hand side an instance of the left-hand side".

例如:

>> 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 class 本身不是字符串。

你在这里处理case equality。在这里,它被后代覆盖以提供有意义的语义。在这种情况下,Module 覆盖它。

Case Equality — Returns true if an object is an instance of a module or one of the module's descendants. Of limited use for modules, but can be used in case statements to classify objects by class.

在模块中,=== 的作用类似于 Ruby 的 is_a? 方法。

在您的例子中,它 returns 为假,因为 "Foo".class 不是字符串 class.

的实例
"Foo".class.is_a?(String)
=> false

这与 类 的大小写等价运算符 === 的实现方式有关。使用对象,而不是 object.class

var = "foo"
case var
when String
  puts "bar"
else
  puts "baz"
=> "bar"