×

ruby · level 3 · unit 6 · lesson 4

  1. meet it
  2. guess first
  3. your turn
  4. fix it
  5. nailed it

Tap a green word if you get lost.

meet it

Guards, pins and make patterns smarter.

A adds an if to a pattern: in {total: Integer => total} if total > 100 only fits big orders. A | offers alternatives, so "paid" | "shipped" fits either word. The , ^, compares against a variable you already have, as in {id: ^wanted}, instead of making a new one.

Your own objects can join in. Write deconstruct_keys(keys) to hand back a hash of fields, and hash patterns will match your objects. Data and Struct objects already have it, which is one more reason to use them for values.

Order = Data.define(:id, :total, :status)
def check(order, wanted)
  case order
  in {id: ^wanted, status: "paid" | "shipped"}
    "Order #{wanted} is on its way"
  in {total: Integer => total} if total > 100
    "Big order needs approval"
  else
    "Nothing to do"
  end
end
puts check(Order.new(id: 7, total: 30, status: "paid"), 7)
puts check(Order.new(id: 8, total: 250, status: "new"), 7)
puts check(Order.new(id: 9, total: 20, status: "new"), 7)

Ruby hands deconstruct_keys the keys the pattern asks for, so a careful class can work out only those.