Case equality operator

suggest change

Also known as triple equals.

This operator does not test equality, but rather tests if the right operand has an IS A relationship with the left operand. As such, the popular name case equality operator is misleading.

This SO answer describes it thus: the best way to describe a === b is “if I have a drawer labeled a, does it make sense to put b in it?” In other words, does the set a include the member b?

Examples (source)

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

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

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

Classes that override ===

Many classes override === to provide meaningful semantics in case statements. Some of them are:

╔═════════════════╦════════════════════╗
║      Class      ║     Synonym for    ║
╠═════════════════╬════════════════════╣
║ Array           ║ ==                 ║
║                 ║                    ║
║ Date            ║ ==                 ║
║                 ║                    ║
║ Module          ║ is_a?              ║
║                 ║                    ║
║ Object          ║ ==                 ║
║                 ║                    ║
║ Range           ║ include?           ║
║                 ║                    ║
║ Regexp          ║ =~                 ║
║                 ║                    ║
║ String          ║ ==                 ║
╚═════════════════╩════════════════════╝

Recommended practice

Explicit use of the case equality operator === should be avoided. It doesn’t test equality but rather subsumption, and its use can be confusing. Code is clearer and easier to understand when the synonym method is used instead.

# Bad
Integer === 42
(1..5) === 3
/ell/ === 'Hello'

# Good, uses synonym method
42.is_a?(Integer)
(1..5).include?(3)
/ell/ =~ 'Hello'

Feedback about page:

Feedback:
Optional: your email if you want me to get back to you:



Table Of Contents