Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the "===" operator do in Ruby? [duplicate]

Tags:

ruby

People also ask

What is the effect of === operator?

Identical Operator === The comparison operator called as the Identical operator is the triple equal sign “===”. This operator allows for a much stricter comparison between the given variables or values. This operator returns true if both variable contains same information and same data types otherwise return false.

What is the name of this operator === in Ruby?

Triple Equals Operator (More Than Equality) Our last operator today is going to be about the triple equals operator ( === ). This one is also a method, and it appears even in places where you wouldn't expect it to. Ruby is calling the === method here on the class.

What does == === mean?

The === operator means "is exactly equal to," matching by both value and data type. The == operator means "is equal to," matching by value only.

What is the difference between double == and triple === equals?

Double Equals ( == ) checks for value equality only. It inherently does type coercion. This means that before checking the values, it converts the types of the variables to match each other. On the other hand, Triple Equals ( === ) does not perform type coercion.


Just like with every other method in Ruby (or actually pretty much any object-oriented language),

a === b

means whatever the author of a's class wants it to mean.

However, if you don't want to confuse the heck out of your colleagues, the convention is that === is the case subsumption operator. Basically, it's a boolean operator which asks the question "If I have a drawer labelled a would it make sense to put b in that drawer?"

An alternative formulation is "If a described a set, would b be a member of that set?"

For example:

 (1..5) === 3           # => true
 (1..5) === 6           # => false

Integer === 42          # => true
Integer === 'fourtytwo' # => false

  /ell/ === 'Hello'     # => true
  /ell/ === 'Foobar'    # => false

The main usage for the === operator is in case expressions, since

case foo
when bar
  baz
when quux
  flurb
else
  blarf
end

gets translated to something (roughly) like

_temp = foo

if bar === _temp
  baz
elsif quux === _temp
  flurb
else
  blarf
end

Note that if you want to search for this operator, it is usually called the triple equals operator or threequals operator or case equality operator. I really dislike those names, because this operator has absolutely nothing whatsoever to do with equality.

In particular, one would expect equality to be symmetric: if a is equal to b, then b better be also equal to a. Also, one would expect equality to be transitive: if a == b and b == c, then a == c. While there is no way to actually guarantee that in a single-dispatch language like Ruby, you should at least make an effort to preserve this property (for example, by following the coerce protocol).

However, for === there is no expectation of either symmetry or transitivity. In fact, it is very much by design not symmetric. That's why I don't like calling it anything that even remotely resembles equality. It's also why I think, it should have been called something else like ~~~ or whatever.


Thanks for your edit Jacob, I was about to call you out ;) I'll post a couple of examples anyway. The implementation of === differs depending on type. For example:

(1...3) === 2
=> true

/test/ === "this is a test"
=> true

case 'test'
when /blah/
  "Blach"
when /test/
  "Test"
else
  "Fail"
end
=> "Test"

Stephen, checkout http://ruby-doc.org/docs/ProgrammingRuby/ (the "Pickaxe"), it should be able to help you out with questions such as this in the future.


In Ruby, the === operator is used to test equality within a when clause of a case statement. In other languages, the above is true.

To my knowledge, Ruby doesn't have true operators, they are all methods which are invoked on the LHS of the expression, passing in the RHS of the expression. So, really, you could override any "operator" you want in your classes to perform whatever the heck you want (analogous to operator overloading in C++).