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
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.
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
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With