Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between equal?, eql?, ===, and ==?

I am trying to understand the difference between these four methods. I know by default that == calls the method equal? which returns true when both operands refer to exactly the same object.

=== by default also calls == which calls equal?... okay, so if all these three methods are not overridden, then I guess ===, == and equal? do exactly the same thing?

Now comes eql?. What does this do (by default)? Does it make a call to the operand's hash/id?

Why does Ruby have so many equality signs? Are they supposed to differ in semantics?

like image 383
denniss Avatar asked Aug 23 '11 06:08

denniss


People also ask

What is difference between == === EQL and equal?

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. In the example above, we have two strings with the same value. However, they are two distinct objects, with different object IDs.

What is the difference between equal () and ==?

equals() is a method of Object class. == should be used during reference comparison. == checks if both references points to same location or not. equals() method should be used for content comparison.

Is there any difference between == operator and === operator?

The main difference between the == and === operator in javascript is that the == operator does the type conversion of the operands before comparison, whereas the === operator compares the values as well as the data types of the operands.

What is the difference between == and === example?

== is used for comparison between two variables irrespective of the datatype of variable. === is used for comparision between two variables but this will check strict type, which means it will check datatype and compare two values.


1 Answers

I'm going to heavily quote the Object documentation here, because I think it has some great explanations. I encourage you to read it, and also the documentation for these methods as they're overridden in other classes, like String.

Side note: if you want to try these out for yourself on different objects, use something like this:

class Object   def all_equals(o)     ops = [:==, :===, :eql?, :equal?]     Hash[ops.map(&:to_s).zip(ops.map {|s| send(s, o) })]   end end  "a".all_equals "a" # => {"=="=>true, "==="=>true, "eql?"=>true, "equal?"=>false} 

== — generic "equality"

At the Object level, == returns true only if obj and other are the same object. Typically, this method is overridden in descendant classes to provide class-specific meaning.

This is the most common comparison, and thus the most fundamental place where you (as the author of a class) get to decide if two objects are "equal" or not.

=== — case equality

For class Object, effectively the same as calling #==, but typically overridden by descendants to provide meaningful semantics in case statements.

This is incredibly useful. Examples of things which have interesting === implementations:

  • Range
  • Regex
  • Proc (in Ruby 1.9)

So you can do things like:

case some_object when /a regex/   # The regex matches when 2..4   # some_object is in the range 2..4 when lambda {|x| some_crazy_custom_predicate }   # the lambda returned true end 

See my answer here for a neat example of how case+Regex can make code a lot cleaner. And of course, by providing your own === implementation, you can get custom case semantics.

eql?Hash equality

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. For objects of class Object, 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 eql?, so:

1 == 1.0     #=> true 1.eql? 1.0   #=> false 

So you're free to override this for your own uses, or you can override == and use alias :eql? :== so the two methods behave the same way.

equal? — identity comparison

Unlike ==, the equal? method should never be overridden by subclasses: it is used to determine object identity (that is, a.equal?(b) iff a is the same object as b).

This is effectively pointer comparison.

like image 159
jtbandes Avatar answered Oct 19 '22 01:10

jtbandes