What are the differences between eql?, equal?, ==, and === in Ruby?
Why does Ruby have so many different types of equalities and what are the differences?
What is .eql? ?
Eql? can be translated as a ‘Generic Equality’. This method returns true if the object and other have the same value. The eql? method returns true if obj and other refer to the same hash key. This is used by Hash to test members for equality. In most classes, eql? is identical to ==.
For any pair of objects where eql? returns true, the hash value of both objects must be equal.
The subclasses general continue the same concept, but there are some exceptions, like Numeric types, that perform type conversion across ==, but not across eql?.
1== 1.0 => true1.eql? 1.0=> false
What is equal?
Equal is another method, which determines the object identify. In other terms it determines if a.equal?(b) if and only if a is the same object as b. For the object to be the equal?, they must contain the exact same object_id.
obj = "a"other = obj.dupobj.object_id => 70243632756780other.object_id= > 70243665867220
obj == other => trueobj.equal? other => falseobj.equal? obj => true
In this example, even though other is a duplicate of obj and has the same value as obj, it is not equal? to obj. They two have different object_id.
What is ==?
== is also known has value comparison. It is the most common used equality comparison used in Ruby. == will return true if an obj and another obj are the same obj.
1 == 1.0 => true[1, 2, 3] == [1, 2, 3] => truestr1 = "this is a string"str2 = "this is a string"str1 == str2 => true"2" == 2 => false
What is === ?
=== is also known as Case Equality Operator, Membership Operator, and Triple Equals. The === is similar to ==, but can be very different in its context. Lets break this down a little farther.
Ranges
A range in Ruby has a starting point and an ending point, for example 1 to 10 can be displayed as (1..10). With ranges, === works similarly to include?. It will check if the value is within the range or a member of the range.
(1..10) === 3 => true(1..10).include?(3) => true(1..10) === 12 => false(1..10).include?(13) => false
Regex/Regular Expressions
Regex is a specific language for matching against patters in text. In regex, === acts similarly to .match?
/abc/ === "abcdef" => true/abc/.match?('abcdef') => true/hij/ === "abcdef" => false/hij/.match?("abcdef") => false
Classes
Ruby contains classes such as Integer, String, ex. To check the type of class, you can use is_a?. With classes === works just like is_a?
String === "hello" => true"hello".is_a?(String) => trueInteger === "is this an integer" => false"is this an integer".is_a?(Integer) => false
Case Expressions
Case expressions implicitly use the === operator on case/when statements. The operator is working under the hood.
temp = 20case temp when (10..30) puts "in temp" else puts "not in temp"end=> in temp
is the same as
temp = 20if (10..30) === temp puts "in temp" else puts "not in temp"end=> in temp
There are many uses and subtly differences with the equality operators in Ruby. With the correct tool, they can be very powerful.