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

target
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}"
  1. 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  end14end
  2. do |record|

    pass 1 of 3
    6records.each do |record[:info, "ready"]|7  case record8  in [kind, text]
    All 3 passes — pass 1 is the card above
    passrecordkindtargettextrecordsmessagefound
    1[:info, "ready"]
    2[:warn, "hot"]warnwarnhothotfalse true
    3[:done, "ok"][[:info, "ready"], [:warn, "hot"], [:done, "ok"]]
  3. message ← hot, found ← true

    8in [kind, text]9  if !foundfalse && kindwarn == targetwarn10    message→ hot = texthot11    found→ true = true12  end
  4. puts "target=#{target}"

    16puts "target=#{targetwarn}"17puts "message=#{messagehot}"
    outputtarget=warn
    message=hot
  1. 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  end14end
  2. do |record|

    pass 1 of 3
    6records.each do |record[:info, "ready"]|7  case record8  in [kind, text]
    All 3 passes — pass 1 is the card above
    passrecordkindtargettextrecordsmessagefound
    1[:info, "ready"]infoinforeadyreadyfalse true
    2[:warn, "hot"]
    3[:done, "ok"][[:info, "ready"], [:warn, "hot"], [:done, "ok"]]
  3. message ← ready, found ← true

    8in [kind, text]9  if !foundfalse && kindinfo == targetinfo10    message→ ready = textready11    found→ true = true12  end
  4. puts "target=#{target}"

    16puts "target=#{targetinfo}"17puts "message=#{messageready}"
    outputtarget=info
    message=ready
  1. 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  end14end
  2. do |record|

    pass 1 of 3
    6records.each do |record[:info, "ready"]|7  case record8  in [kind, text]
    All 3 passes — pass 1 is the card above
    passrecordrecords
    1[:info, "ready"]
    2[:warn, "hot"]
    3[:done, "ok"][[:info, "ready"], [:warn, "hot"], [:done, "ok"]]
  3. puts "target=#{target}"

    16puts "target=#{targetmissing}"17puts "message=#{messagenone}"
    outputtarget=missing
    message=none