为什么" foo" .class === String返回false?

时间:2015-11-30 23:43:26

标签: ruby string boolean equality

当我没想到这件事时,我很好奇:

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中的===?我很困惑。

3 个答案:

答案 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"