Ruby Pattern Guards
A pattern can check shape but not size or range. A guard adds an if or unless check to an in clause for exactly those tests.
An if guard adds a size check
The reading matches the pair shape on both clauses. The guard sends high readings to the first clause and the rest below.
reading = [25, "warm"]
case reading
in [Integer, String] if reading.first >= 20
puts "high reading"
in [Integer, String]
puts "low reading"
endAn unless guard flips the check
The unless guard passes when its condition is false. The small pair takes the first clause and the plain clause stays as backup.
pair = [3, "cat"]
case pair
in [Integer, String] unless pair.first > 10
puts "small number with a word"
in [Integer, String]
puts "big number with a word"
endA failed guard falls through
Both pairs match the guarded shape, but only the second passes its guard. The first pair lands on the unguarded clause below.
pairs = [[4, "ant"], [30, "bear"]]
pairs.each do |pair|
case pair
in [Integer, String] if pair.first > 10
puts "big pair"
in [Integer, String]
puts "small pair"
end
endA guard reads a bound name
The hash pattern binds count before the guard runs. The guard then compares that bound count against ten.
order = {item: "pen", count: 12}
case order
in {count:} if count > 10
puts "bulk order"
in {count:}
puts "small order"
endExample
entries = [[15, "Ana"], [3, "Bo"], [15, "Cy"]]
entries.each do |entry|
case entry
in [score, name] if score > 10
puts "#{name} passed well"
in [score, name] unless score > 3
puts "#{name} needs practice"
in [score, name]
puts "#{name} just passed"
end
endKey points
- A guard adds an if or unless check after the pattern in the same clause.
- The pattern must match before the guard is checked at all.
- When a guard fails, matching falls through to the next in clause.
- A guard can read names bound by its own pattern.
In this example, both guards read the score bound by their own pattern. The high scores pass the if guard, the low score passes the unless guard, and the plain clause waits for anything in between.
Note
Guards carry the checks a pattern shape cannot express, such as size comparisons.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
A pattern matches but its guard fails. What happens next?