It all started with Nick asking a question like this in Singapore Ruby Brigade. How come?
String === String => false # but String == String => true
Let’s start with the easy one first:
Equality (==, eql?, equal?)
#== is the common equality method that compares object values, ignoring the object id. #eql? is the alias of #==, so they are the same. Btw the “#” prefix means it is an instance method (just in case), without the prefix, it means a class method.
The stricter version of is #equal? compares the object id. Example:
"test" == "test"
# returns true, both have the same value, i.e. "test"
"test".equal?("test")
# returns false, because "test" (left) is a different object from "test" (right), where "test".__id__ != "test".__id__
Case Equality (===)
=== is the case equality method, in English it means it is called internally when you use ‘case’ statement, but of course, it can also be called outside the case statement.
=== method functions differently, depending on the caller class type.
If you call it on a Class, it will check if the compared object is an instance/descendant of the class. On Object, it is the same with #== method. Please refer to Ruby documentation for more information on how it performs on different class types.
String === "test" # returns true because "test" is an instance of String "test" === "test" # returns true, because both objects have the same value or "==" returns true "test" === "different test" # returns false, because the two objects have different values.
Just a bit more spice, on Ruby on Rails (RoR) framework, the Range class overrides “===” method to returns true if the compared value is found in the in the range values.
1..10 === 1 # returns true
1..10 === 11 # returns false
case var
when 1..10
"do some stuff here"
when 11..20
"do something else here"
else
"out of range"
end
So back to the one-million-dollar question, why then String === String returns false?
Calling String in the runtime environment, returns a Class object that represents String class type. If you call String.__id__, it will return the object id of Class object. Thus:
String === String # returns false, because String (right) is treated as a Class object, passed as an argument to String "===" method.
And… I think you get it, obviously Class object is not an instance of String class. Sweet.
And why String == String returns true?
You should be able to answer it by now. =)

Add Your Comment