Ruby Pattern Binding
Pattern binding gives matched parts their own names. The rightward arrow binds a value to a pattern, and the pin compares against a value already held.
The arrow binds the matched parts
The pair is matched against an array pattern with two names. Both names then print on their own lines.
pair = [3, "cat"]
pair => [number, word]
puts number
puts wordThe arrow can bind one part
The hash pattern names only count and renames it amount. The rest of the hash is left alone.
order = {item: "pen", count: 4}
order => {count: amount}
puts amountThe pin matches a stored value
target holds 5 before the case starts. The pin clause matches only the pair that starts with that stored value.
target = 5
pairs = [[5, "cat"], [9, "dog"]]
pairs.each do |pair|
case pair
in [^target, String]
puts "starts with the target"
else
puts "other start"
end
endA failed arrow match raises
The array holds two values but the pattern asks for three names. The match fails and the error names the length mismatch.
short = [5, 6]
short => [first, second, third]A one-line match as a condition
Each if line carries its own one-line match. Only the condition whose pattern fits runs its body.
pair = [3, "cat"]
if pair in [Integer, String]
puts "number then word"
end
if pair in [String, Integer]
puts "word then number"
endExample
target = 10
rows = [[10, "Ana"], [4, "Bo"], [10, "Cy"]]
rows.each do |row|
case row
in [^target, name]
puts "#{name} hit the target"
in [points, name]
puts "#{name} scored #{points}"
end
end
best = rows.first
best => [top_score, top_name]
puts "#{top_name} leads with #{top_score}"Key points
- The rightward form value => pattern checks the pattern and binds the matched parts to names.
- Binding one part of a hash gives that part its own name for later lines.
- The pin ^name matches against a value already stored instead of binding a new one.
- A failed rightward match raises NoMatchingPatternError.
- A one-line match after if works as a condition for that line.
In this example, the pin clause catches the rows that start with the stored target and binds the name beside it. The other row binds both parts and prints its score. The arrow then binds the best row to two fresh names for the last line.
Note
The bound names live on after the match, ready for the lines below.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
What does the pin ^name do inside a pattern?