Pattern matching
was introduced in Ruby 2.7,
a feature commonly found in functional programming languages like Scala.
Unlike other programming languages,
pattern matching in Ruby uses the case
statement.
Instead of using the when
keyword,
the keyword in
is used.
Let us check the below example to see how pattern matching works in Ruby.
We have passed a variable data
(a hash) and an expression [1, 2, 3]
to the case
statement.
The data
variable values and array indexes are matched with
the pattern of every in
clause.
Once a pattern has matched the code within that in
clause gets executed.
Besides structural checks, one of the features of pattern matching is the binding of the matched parts to local variables.
As seen in the above example,
the local variable a
was assigned the value 1
when an
expression matches a pattern.
Due to the variable binding feature,
the existing local variable cannot be used straightforwardly as a sub-pattern.
For the below example,
the variable current_price
should not have changed.
But because of variable binding, the value got updated.
To avoid such issues, “variable pinning” operator (^) can be used, which will use the value for pattern matching.
Before
The pin operator worked fine in the case of variables, constants, and literals but failed when an expression or range is passed.
Let’s take an example where we have the following JSON data:
We want to match all children of Alice in the range 2 to 4. Using pattern matching, if we try to pass the age parameter as a range it will fail with a syntax error.
After
Ruby 3.1 introduces a pin operator against expressions to fix the above issue. It has been committed to the trunk and can be tested/played using Ruby 3.1.0-dev through RubyBuild.
We can now pass expressions and range using pin operator and, it should work fine without raising an error.
Note:
Pattern matching is still an experimental feature and, a warning is displayed when it is used.