Ruby is_a? vs ===

时间:2014-03-03 15:52:40

标签: ruby-on-rails ruby operators

is_a?===之间有什么区别?

运行此代码:

puts myObj.class
puts myObj.is_a?(Hash)
puts myObj === Hash   #Curious 
puts Hash  === myObj

输出:

Hash
true
false        #Why?
true

3 个答案:

答案 0 :(得分:6)

许多Ruby的内置类(如String,Range和Regexp)提供了自己的===运算符实现,也称为case-equality,triple equals或threequals。因为它在每个类中的实现方式不同,所以它的行为会有所不同,具体取决于调用它的对象类型。通常,如果右侧的对象“属于”或“是左侧对象的成员”,则返回true。例如,它可用于测试对象是否是类(或其子类之一)的实例。

String === "zen"  # Output: => true
Range === (1..2)   # Output: => true
Array === [1,2,3]   # Output: => true
Integer === 2   # Output: => true

使用可能最适合工作的其他方法可以获得相同的结果。通常,在不牺牲效率和简洁性的情况下,通过尽可能明确地编写易于阅读的代码通常会更好。

2.is_a? Integer   # Output: => true
2.kind_of? Integer  # Output: => true
2.instance_of? Integer # Output: => false

请注意,最后一个示例返回false,因为整数(如2)是Fixnum类的实例,它是Integer类的子类。如果对象是给定类或任何子类的实例,则===is_a?kind_of?方法返回true。 instance_of?方法更严格,只有当对象是该类的实例而不是子类时才返回true。

is_a?kind_of?方法在Kernel模块中实现,该模块由Object类混合。两者都是同一方法的别名。我们来验证:

Kernel.instance_method(:kind_of?) == Kernel.instance_method(:is_a?)
# Output: => true

this blog post about ruby operators.

的更多信息

答案 1 :(得分:3)

它们本质上大致相同,但===也可以在子类中重写。

===通常是一个简单的包装器,主要是为了使case结构可以隐式使用它。默认情况下,它是wrapper around Object#is_a?(请参阅来源)。

然而,这两个意图是等效结构。

答案 2 :(得分:1)

清除示例

1)$> Integer === 1 # => true 

2)$> 1 === Integer # => false

1)1 整数的实例,但是2)整数不是1的实例。

但如果是其任何子类的实例,也会返回true,例如:

$ > Numeric === 1   # => true 
$ > Numeric === 1.5 # => true

$ > Fixnum === 1    # => true 
$ > Fixnum === 1.5  # => false