Difference Between ==, eql?, equal? in ruby
Equality operators: == and !=
The == operator, also known as equality or double equal, will return true if both objects are equal and false if they are not.
str1 = “This is string”
str2 = “This is string”
str1 == str2 #Output: => truestr1 != str2 #Output: => false
When comparing numbers of different types (e.g., integer and float), if their numeric value is the same, == will return true.
2 == 2.0 # Output: => true
eql? method returns true if
other refer to the same hash key. This is used by
Hash to test members for equality. For objects of class
eql? is synonymous with
==. Subclasses normally continue this tradition by aliasing
eql? to their overridden
==method, but there are exceptions.
Numeric types, for example, perform type conversion across
==, but not across
1 == 1.0 #=> true
1.eql? 1.0 #=> false
Unlike the == operator which tests if both operands are equal, the equal method checks if the two operands refer to the same object. This is the strictest form of equality in Ruby.
Example: a = “xyz” and b = “xyz”
a.object_id # Output: => 20139460
b.object_id # Output :=> 19972120a.equal? b # Output: => false
In the example above, we have two strings with the same value. However, they are two distinct objects, with different object IDs. Hence, the equal? method will return false.
Let’s try again, only this time b will be a reference to a. Notice that the object ID is the same for both variables, as they point to the same object.
a = "string"
b = aa.object_id # Output: => 18637360
b.object_id # Output: => 18637360a.equal? b # Output: => true
Case equality operator: ===
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
Range Implementation of ===
When the === operator is called on a range object, it returns true if the value on the right falls within the range on the left.
(1..4) === 3 # Output: => true
(1..4) === 2.345 # Output: => true
(1..4) === 6 # Output: => false("a".."d") === "c" # Output: => true
("a".."d") === "e" # Output: => false
Implicit usage of the === operator on case/when statements
This operator is also used under the hood on case/when statements. That is its most common use.
minutes = 15case minutes
puts "no match"
end# Output: match
In the example above, if Ruby had implicitly used the double equal operator (==), the range 10..20 would not be considered equal to an integer such as 15. They match because the triple equal operator (===) is implicitly used in all case/when statements. The code in the example above is equivalent to:
minutes = 15
if (10..20) === minutes
puts "no match"
# Output: match