Table of contentsClick link to navigate to the desired location
This content has been automatically translated from Ukrainian.
There are several ways to compare in Ruby. They are similar at first glance, but work completely differently.
== (values equality test)
- Checks whether have objects with the same content.
- Often redefined in classes (String, Array, Hash) to compare meaning rather than identity.
a = "hello" b = "hello" a == b # => true a.equal?(b) # => false
== asks, "Are these objects of equal content?"
equal? (object identity verification)
- Checks whether it's the same thing object in memory.
- Not redefined in classes, always compares object id.
a = "hello" b = "hello" c = a a.equal?(b) # => false a.equal?(c) # => true
Here, to understand all this work, you need to know what an object is in Ruby.
eql? (strict equality check for hashes and numbers)
- Checks value and type.
- Mainly used in hashes for keys.
1 == 1.0 # => true 1.eql?(1.0) # => false, because different classes (Integer vs Float)
eql? more severe than ==.
=== (case-match operator)
- It is used mainly in case construction (let's analyze it below).
- Behaves differently for different classes:
- In classes (String, Integer) - checks if an object belongs to the class (is_a?).
- In regular expressions, checks whether the string falls under the pattern.
- In Range - whether an object falls within a range.
case 5 when 1..10 "In range" # => "In range" end String === "hello" # => true /ell/ === "hello" # => true
Let's consider a case example in a little more detail. How does case ... when work in Ruby?
Syntax:
case object when sample1 code 1 when sample2 code 2 else code_by_order end
What happens under the hood
Ruby does something like this:
if sample1 === object code 1 elsif sample2 === object code 2 else code_by_order end
That is when automatically uses === for comparison with case value.
Examples for different types follow
Range (Range)
case 5 when 1..10 "In range" else "Out of range" end # => "In range"
Works like this, like Ruby executes (this is pseudo code):
(1..10) === 5 # => true
But it is important to note that normal use === on numbers or other types does not necessarily work the same way:
10 === (1..20) # => false 10 == (1..20) # => false (1..20) == 10 # => false
Here Range#=== checks if a number is in the range.
Class
case "hello" when String "That's a line" when Integer "It's a number" end # => "This is a string"
Ruby performs:
String === "hello" # => true Integer === "hello" # => false
For classes === — is the abbreviation for obj.is_a?(Class).
c) Regular expression
case "hello" when /ell/ "Coincidence with pattern" else "No match" end # => "Coincidence with pattern"
Under the hood:
/ell/ === "hello" # => true
For Regexp, === checks if the string matches the pattern.
We moved a little off the subject === and moved on to case (because there === under the hood). Such a simple operator, but does different things.
To make it easier to remember:
- case x; when y is not x == y, but y === x.
- === works differently depending on the type of y:
- Class -> is_a?
- Range -> include?
- Regexp -> =~ (line match)
This allows you to write conditions very flexibly.
This post doesn't have any additions from the author yet.