Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ruby is_a? vs ===

What is the difference between is_a? and ===?

Running this code:

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

The output is:

Hash
true
false        #Why?
true
like image 896
Alex Avatar asked Mar 03 '14 15:03

Alex


3 Answers

Many of Ruby's built-in classes, such as String, Range, and Regexp, provide their own implementations of the === operator, also known as case-equality, triple equals or threequals. Because it's implemented differently in each class, it will behave differently depending on the type of object it was called on. Generally, it returns true if the object on the right "belongs to" or "is a member of" the object on the left. For instance, it can be used to test if an object is an instance of a class (or one of its subclasses).

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

The same result can be achieved with other methods which are probably best suited for the job. It's usually better to write code that is easy to read by being as explicit as possible, without sacrificing efficiency and conciseness.

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

Notice the last example returned false because integers such as 2 are instances of the Fixnum class, which is a subclass of the Integer class. The ===, is_a? and kind_of? methods return true if the object is an instance of the given class or any subclasses. The instance_of? method is stricter and only returns true if the object is an instance of that exact class, not a subclass.

The is_a? and kind_of? methods are implemented in the Kernel module, which is mixed in by the Object class. Both are aliases to the same method. Let's verify:

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

More info at this blog post about ruby operators.

like image 199
BrunoF Avatar answered Nov 13 '22 05:11

BrunoF


Clear example

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

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

1) 1 is an instance of Integer, but 2) Integer is not an instance of 1.

But also returns true if is an instance of any of its subclasses, for example:

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

$ > Fixnum === 1    # => true 
$ > Fixnum === 1.5  # => false
like image 20
Rafa Paez Avatar answered Nov 13 '22 03:11

Rafa Paez


They are mostly the same in essence, but === can also be overridden in subclasses.

=== is usually a light wrapper around something, mainly so that the case construct can use it implicitly. By default it's a wrapper around Object#is_a? (see source).

These two however are intended to be equivalent constructs.

like image 39
Agis Avatar answered Nov 13 '22 04:11

Agis