{"atom":"regression/issue-18-react-phasers","family":"regression","slug":"issue-18-react-phasers","header":{"atom":"regression/issue-18-react-phasers","kind":"whole-program — a minimal repro, not yet reduced to an atom","source":"curated"},"axes":null,"cols":null,"engines":["rakudo-2026.07","rakupp-3.14.0"],"kinds":["ref","pp"],"defFrom":"rakupp:t/regression/issue-18-react-phasers.raku","counts":{"a":1,"f":0,"d":0,"c":0,"r":0,"n":0},"files":["atoms/regression/issue-18-react-phasers.grid"],"records":[["0001","","# Issue #18: LAST/QUIT phasers in react whenevers + deferred activation.\n# Three behaviors, each matching Rakudo's reference output:\n#   1. the react BODY runs before any whenever drains — a say at the body's\n#      end prints before the first emitted value;\n#   2. a LAST phaser fires when a whenever'd supply is exhausted, and it sees\n#      the block's parameter as of the LAST invocation;\n#   3. a die in a whenever body KILLS the react and propagates (it used to be\n#      swallowed, leaving an interval ticker running forever) — and a QUIT\n#      phaser does NOT catch it (QUIT is for the source's own quit; the\n#      issue's Rakudo output confirms).\n# Runs under both engines: programs go through $*EXECUTABLE.\n\nmy $work = $*TMPDIR.add(\"issue18-$*PID\");\nmkdir $work;\n\nmy $fails = 0;\nsub check(Str $desc, Bool $ok) {\n    if $ok {\n        say \"ok - $desc\";\n    }\n    else {\n        $fails++;\n        say \"not ok - $desc\";\n    }\n}\n\nsub run-prog(Str $name, Str $code) {\n    my $f = $work.add($name);\n    $f.spurt($code);\n    my $p = run($*EXECUTABLE, $f.Str, :out, :err);\n    my $out = $p.out.slurp(:close);\n    $p.err.slurp(:close);\n    ($out, $p.exitcode)\n}\n\n# 1 + 2: body-first ordering, LAST sees the last-bound parameter\nmy ($out1, $exit1) = run-prog('t1.raku', q:to/END/);\n    react {\n        whenever <a b c>.Supply -> $c {\n            say $c;\n            LAST { say \"Done with $c\" }\n        }\n        say \"Starting...\";\n    }\n    END\ncheck('react body runs before the whenever drains, LAST sees $c',\n      $out1 eq \"Starting...\\na\\nb\\nc\\nDone with c\\n\" && $exit1 == 0);\n\n# 3: a die in a whenever body kills the react (no hang) and QUIT stays quiet\nmy ($out2, $exit2) = run-prog('t2.raku', q:to/END/);\n    react {\n        whenever <a b c>.Supply -> $c {\n            say $c;\n            LAST { say \"Done with $c\" }\n        }\n        whenever Supply.interval(0.2) {\n            die \"something went wrong..\";\n            QUIT { default { say \"oops: {.message}\" }}\n        }\n        say \"Starting...\";\n    }\n    END\ncheck('a die in a whenever body kills the react and propagates',\n      $exit2 != 0);\ncheck('the finished supply still ran its LAST before the die',\n      $out2.contains(\"Done with c\"));\ncheck('QUIT does not catch a body die (reference behavior)',\n      !$out2.contains(\"oops\"));\ncheck('the body say still leads the output',\n      $out2.starts-with(\"Starting...\\n\"));\n\nunlink $work.add($_) for <t1.raku t2.raku>;\nsay $fails == 0 ?? 'PASS' !! 'FAIL';\nexit($fails ?? 1 !! 0);","output ok - react body runs before the whenever drains, LAST sees $c\nok - a die in a whenever body kills the react and propagates\nok - the finished supply still ran its LAST before the die\nok - QUIT does not catch a body die (reference behavior)\nok - the body say still leads the output\nPASS","a",["ok - react body runs before the whenever drains, LAST sees $c …(6 lines)","ok - react body runs before the whenever drains, LAST sees $c …(6 lines)"],0,[["budget","20s"]]]]}