Ruby Pattern Matching
Ruby Pattern Matching
Model comparison is a function that allows in-depth matching of structural values: structure check and comparison of corresponding parts and local variables.
Ruby Pattern Matching Syntax
Pattern matching in Ruby is done using case statements. When using keywords, do not use them normally, but enter them. In addition, it supports using if or unless statements.
case [variable or expression]
in [pattern]
...
in [pattern] if [expression]
...
else
...
End
Case statements can take variables or expressions and match them to the pattern specified in the clause. If or unless statements can also be specified after the pattern. Here, the equality check also uses === as a normal case statement. This means you can combine subsets and class scenarios.
The basic format of pattern matching is a case statement. This is not much different from the case statement matching conditions you already know in Ruby, except we are only replacing “when” with “in”. If your use case is basic, you will notice there is no difference between using in or when, as shown in the following example.
grade = 'C'
case grade
when 'A' then puts 'Amazing effort'
when 'B' then puts 'Good work'
when 'C' then puts 'Well done'
when 'D' then puts 'Room for improvement'
else puts 'See me'
end
# => Well done
Pattern Matching Objects in Ruby
Objects are not exempted from the pattern matching:
case {a: 1, b: 2}
in {a: Integer}
"matches" # By default, all object matches are partial
in {a: Integer, **}
"matches" # and is same as {a: Integer}
in {a: a}
"matches" # and the value of variable a is now 1
in {a: Integer => a}
"matches" # and the value of variable a is now 1
in {a: 1, b: b}
"matches" # and the value of variable b is now 2
in {a: Integer, **nil}
"does not match" # This will match only if the object has a and no other keys.
End
Array Pattern Match
There are different ways to match against arrays. Basically, pattern matching can be done against the same elements in the array.
arr = [1 ,2]
case arr
in [1, 2] then puts :match
in [3, 4] then puts :no_match
end
# => match
Pattern Matching with =>/in Without case
If your Ruby is version 3 and above, it is easier to use more pattern-matching magic. Starting with Ruby 3, pattern matching can be done in one line without a case statement:
[1, 2, "Three"] => [Integer => one, two, String => three]
puts one # 1
puts two # 2
puts three # Three
# Same as above
[1, 2, "Three"] in [Integer => one, two, String => three]
As the “an else” clause is not included in the syntax above, it is very useful when the data structure is known in advance.
Hash Pattern Matching
Hash Pattern Matching works similarly to arrays, with a few crucial differences. First, pattern matching is only compatible with symbol keys and not string keys. The reason for this has to do with the way Ruby matches against a hash. This might not be the same in the upcoming Ruby version. Secondly, unlike arrays, you can match parts of a hash without worrying about the fact that there might be an additional key.
The matching can be done against the actual hash.
case { a: 'phone', b: 'laptop' }
in { a: 'Coconut', b: 'Monkey' }
puts :no_match
in { a: 'Coconut', b: 'Monkey' }
puts :match
end
# => match
We can match against a hash and assign values to variables.
case { a: 'Coconut', b: 'Monkey' }
in { a: a, b: b }
puts a
puts b
end
# => Coconut
# => Monkey
Ruby Pattern for Rightward assignment
It is common practice to use Ruby to place the variable to the left of the expression that binds the value to the variable. A rightward assignment allows you to deconstruct an object and assign the value of the variable to the right. Instead of = as a hash rocket=>.
login = { username: 'Upstack', password: 'codeword' }
login => { username: username }
puts "Logged in with username #{username}"
#=> "Logged in with username Upstack"
The case/in format is best used when there are some conditions you can match, and you need to examine them. The hash rocket syntax is best recommended when the data structure you are creating is known, such as the example of login credentials used above.
What can we use in pattern matching?
Literals
When matching patterns in Ruby, you can use letters: Booleans, nil, Numbers, Strings, Symbols, arrays, Hashes, Ranges, Regular Expressions, Procs.
case 2
in (1..3)
: match
in Integer
:too_late_for_match
end
=> :match
Variables
In addition, we can use variables that were used in the example above.
irb> array = [1, 2, 3]
=> [1, 2, 3]
case [1, 2, 4]
in array
:match
end
irb> array
=> [1, 2, 4]
If you want to compare what is present in our variable with an expression, we will be using ^:
irb> array
=> [1, 2, 4]
case [1, 2, 3]
in ^array
:no_match
else
:match
end
irb> array
=> [1, 2, 4]
Alternative pattern
Another thing we can use is the alternative pattern:
case 5
in 6
:no_match
in 2 | 3 | 5
:match
end
=> :match
Upstack - matches startups with vetted software developers! Ready for a match made in Heaven? Get in touch!