The equality methods in ruby confuse me about once a month. So it’s time to permanently embed this information into my brain.
The first confusing part is remembering which object is doing the comparing.
1 == 2 # It makes more sense if you think of it like this 1.==(2)
1 calls it’s method == with the argument 2. I like to think of it as 1 is put in charge of checking if it equals 2. 2 is just along for the ride.The second confusing part is there are several methods that deal with equality but in a slightly different ways.
equal?
Returns true if the object_id’s are equal. Rarely used, and should not be overridden. You can basically forget out it.
a = b = "bob" a.equal? b # true a.equal? "bob" # false since the object_id for the literal "bob" is different than will be different
==
The most common equality operator. It is generally used to test the value of objects instead of the object_id’s.
</pre> string = "bob" array = [1,2,3] array == [1,2,3] # true string == "bob" # true 1 == 1.0 # true
eql?
Just like == but more strict (i.e. returns false for objects are different types.) As far as I can tell, this is only used to compare hash keys. Like the equal? method, you can basically forget about this one.
string = "bob" string.eql? "bob" # true 1.eql? 1.0 # false since 1 is a Fixnum and 1.0 is a Float
===
Used for case statements. It is full of magic and sprinkled with mystery. This case statement…
case 1 when Numeric then "Number" when String then "String" end # It is equivalent to... if Numeric === 1 then "Number" elsif String === 1 then "String" end
This seems kind of unintuitive since the arguments for === seem to be in the reversed in the case statement. But this technique has more power than greyskull. Check out Regex, Range, and Module to see clever === uses. Also remember a === b may be true, but it’s converse b === a could be false!