Skip to content

Instantly share code, notes, and snippets.

@gfldex

gfldex/caller.raku

Created Jan 2, 2021
Embed
What would you like to do?
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