class CapturedExitcode is Exception { | |
has $.exitcode; | |
} | |
sub embed-script($path --> List) { | |
my $out = Channel.new but role :: { has $.exitcode is rw; }; | |
my $in = Channel.new but role :: { method put(Any:D \value){ self.send: value ~ $?NL } }; | |
my &main := $path.IO.slurp.&EVAL; | |
use nqp; | |
my &disp = &main.multi ?? nqp::getattr(&main, Routine, '$!dispatcher') !! &main; | |
start { | |
my &*EXIT = sub ($exitcode) { | |
CapturedExitcode.new(:$exitcode).throw; | |
} | |
my $*OUT = class :: { | |
method print(|c) { $out.send: |c } | |
method FALLBACK($name, |c) { | |
say "FALLING: $name"; | |
} | |
}.new; | |
my $*IN = $in.Supply.lines; | |
$out.exitcode = disp(); | |
LEAVE { | |
$out.close; | |
} | |
CATCH { | |
when CapturedExitcode { | |
$out.exitcode = .exitcode; | |
} | |
default { | |
say .^name, ': ', .message; | |
put .backtrace».Str | |
} | |
} | |
} | |
$out, $in | |
} | |
my ($out, $in) = embed-script('./script.raku'); | |
start { | |
for ^10 { | |
$in.put: $++; | |
} | |
$in.close; | |
} | |
.print for $out.list; | |
say $out.exitcode; |
#! /usr/bin/env raku | |
constant \frame = gather while my $frame = callframe($++) { | |
take $frame | |
} | |
multi sub MAIN { | |
say 'indirect' if any frame».gist».starts-with('EVAL'); | |
.note for lines; | |
exit 42; | |
say 'alive'; | |
} | |
multi sub MAIN(123) { | |
say "inside"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment