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

Possible Duplicate:
=== vs. == in Ruby

I've seen it used a few times lately but can't figure out what it does. Can anyone illustrate how it works?


Solution 1:

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.

Solution 2:

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.

Solution 3:

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++).