Pattern Matching
Find Pattern
A loop can use pattern matching to find the first record with a matching shape.
find pattern
Pattern matching inside a small loop can stop when the desired record appears.
Find Pattern
find_pattern.rb
Replay: real traced execution (multi-file project)
target = :warn
records = [[:info, "ready"], [:warn, "hot"], [:done, "ok"]]
message = "none"
found = false
records.each do |record|
case record
in [kind, text]
if !found && kind == target
message = text
found = true
end
end
end
puts "target=#{target}"
puts "message=#{message}"
target = :info
records = [[:info, "ready"], [:warn, "hot"], [:done, "ok"]]
message = "none"
found = false
records.each do |record|
case record
in [kind, text]
if !found && kind == target
message = text
found = true
end
end
end
puts "target=#{target}"
puts "message=#{message}"
target = :missing
records = [[:info, "ready"], [:warn, "hot"], [:done, "ok"]]
message = "none"
found = false
records.each do |record|
case record
in [kind, text]
if !found && kind == target
message = text
found = true
end
end
end
puts "target=#{target}"
puts "message=#{message}"
target ← warn, records ← [[:info, "ready"], [:warn, "hot"], [:done, "ok"]]
1target→ warn = :warn #@target=:info, :missing2records→ [[:info, "ready"], [:warn, "hot"], [:done, "ok"]] = [[:info, "ready"], [:warn, "hot"], [:done, "ok"]]3message→ none = "none"4found→ false = false56records[[:info, "ready"], [:warn, "hot"], [:done, "ok"]].each do |record|7 case record8 in [kind, text]9 if !found && kind == target10 message = text11 found = true12 end13 end14enddo |record|
pass 1 of 36records.each do |record[:info, "ready"]|7 case record8 in [kind, text]All 3 passes — pass 1 is the card above pass recordkindtargettextrecordsmessagefound1 [:info, "ready"] — — — — — — 2 [:warn, "hot"] warn warn hot — hot false → true 3 [:done, "ok"] — — — [[:info, "ready"], [:warn, "hot"], [:done, "ok"]] — — message ← hot, found ← true
8in [kind, text]9 if !foundfalse && kindwarn == targetwarn10 message→ hot = texthot11 found→ true = true12 endputs "target=#{target}"
16puts "target=#{targetwarn}"17puts "message=#{messagehot}"outputtarget=warn message=hot
target ← info, records ← [[:info, "ready"], [:warn, "hot"], [:done, "ok"]]
1target→ info = :info2records→ [[:info, "ready"], [:warn, "hot"], [:done, "ok"]] = [[:info, "ready"], [:warn, "hot"], [:done, "ok"]]3message→ none = "none"4found→ false = false56records[[:info, "ready"], [:warn, "hot"], [:done, "ok"]].each do |record|7 case record8 in [kind, text]9 if !found && kind == target10 message = text11 found = true12 end13 end14enddo |record|
pass 1 of 36records.each do |record[:info, "ready"]|7 case record8 in [kind, text]All 3 passes — pass 1 is the card above pass recordkindtargettextrecordsmessagefound1 [:info, "ready"] info info ready — ready false → true 2 [:warn, "hot"] — — — — — — 3 [:done, "ok"] — — — [[:info, "ready"], [:warn, "hot"], [:done, "ok"]] — — message ← ready, found ← true
8in [kind, text]9 if !foundfalse && kindinfo == targetinfo10 message→ ready = textready11 found→ true = true12 endputs "target=#{target}"
16puts "target=#{targetinfo}"17puts "message=#{messageready}"outputtarget=info message=ready
target ← missing, records ← [[:info, "ready"], [:warn, "hot"], [:done, "ok"]]
1target→ missing = :missing2records→ [[:info, "ready"], [:warn, "hot"], [:done, "ok"]] = [[:info, "ready"], [:warn, "hot"], [:done, "ok"]]3message→ none = "none"4found→ false = false56records[[:info, "ready"], [:warn, "hot"], [:done, "ok"]].each do |record|7 case record8 in [kind, text]9 if !found && kind == target10 message = text11 found = true12 end13 end14enddo |record|
pass 1 of 36records.each do |record[:info, "ready"]|7 case record8 in [kind, text]All 3 passes — pass 1 is the card above pass recordrecords1 [:info, "ready"] — 2 [:warn, "hot"] — 3 [:done, "ok"] [[:info, "ready"], [:warn, "hot"], [:done, "ok"]] puts "target=#{target}"
16puts "target=#{targetmissing}"17puts "message=#{messagenone}"outputtarget=missing message=none