Acme-ComeFrom
view release on metacpan or search on metacpan
lib/Acme/ComeFrom.pm view on Meta::CPAN
$chunk .= "
if (\$Acme::ComeFrom::CacheEXPR) {
$pkg\::CACHE[$v->[$iter]] = eval q;$cond->[$iter];
unless exists $pkg\::CACHE[$v->[$iter]];
goto $Mark$v->[$iter] unless
('$label' ne $pkg\::CACHE[$v->[$iter]])$forktext;
}
else {
goto $Mark$v->[$iter] unless
('$label' ne eval q;$cond->[$iter];)$forktext;
}
";
}
else {
$chunk .= "goto $Mark$v->[$iter]" . ( $fork ? " unless fork();" : ';' );
}
}
$chunk =~ s/\n */ /g;
return $chunk;
}
1;
__END__
=head1 NAME
Acme::ComeFrom - Parallel Goto-in-reverse
=head1 VERSION
This document describes version 0.11 of Acme::ComeFrom, released
October 15, 2007.
=head1 SYNOPSIS
use Acme::ComeFrom;
sub func { print "@_" }; func("Start\n");
print "This won't happen\n";
comefrom &func; print "Branch 1\n"; exit;
comefrom &func; print "Branch 2\n";
label: print "This won't happen either\n";
comefrom label; print "Branch 2.1\n"; exit;
comefrom label; print "Branch 2.2\n";
EXPR0: print "To be\n"; exit;
comefrom "EXPR".int(rand(2)); print "Not to be\n";
=head1 DESCRIPTION
B<INTERCAL> programmers have for a long time monopolized the enormously
powerful construct C<COME FROM>, both as a flow-control replacement to
C<goto>, and as a simple way to mark parallel execution branches in
the multi-thread variant.
But now, with B<Acme::ComeFrom>, we Perl hackers can finally be on par
with them in terms of wackiness, if not in obfuscation.
Just like C<goto>, C<comefrom> comes in three different flavors:
=over 4
=item comefrom LABEL
The C<comefrom-LABEL> form finds the statement labeled with C<LABEL>
and jumps to the C<comefrom> each time just I<before> that statement's
execution. The C<comefrom> may not be inside any construct that
requires initialization, such as a subroutine or a C<foreach> loop,
unless the targeting C<LABEL> is also in the same construct.
=item comefrom EXPR
The C<comefrom-EXPR> form expects a label name, whose scope will be
resolved dynamically. This allows for computed C<comefrom>s by
checking the C<EXPR> before every label (a.k.a. watchpoints), so
you can write:
# $i below evaluates in the LABEL's scope
comefrom ("FOO", "BAR", "GLARCH")[$i];
Starting from version 0.05, the value of EXPR is evaluated each time,
instead of the old I<frozen at the first check> behaviour. If this
breaks your code -- as if there's any code based on comefrom --
You may retain the original behaviour by assigning a true value
to C<$Acme::ComeFrom::CacheEXPR>.
=item comefrom &NAME
The C<comefrom-&NAME> form is quite different from the other forms of
C<comefrom>. In fact, it isn't a comefrom in the normal sense at all,
and doesn't have the stigma associated with other C<comefrom>s. Instead,
it installs a post-processing handler for the subroutine, and a jump
would be made just I<after> the subroutine's execution.
=back
If two or more C<comefrom> were applied to the same LABEL, EXPR or NAME,
they will be executed simultaneously via C<fork()>. The forking are
ordered by their occurrances, with the parent process receiving
the last one.
=head1 BUGS
This module does not really parse perl; it guesses label names quite
accurately, but the regex matching the C<comefrom> itself could catch
many false-positives. Perhaps some day a brave soul somewhere will
volunteer to patch this module to use L<PPI> instead...
=head1 ACKNOWLEDGEMENTS
To the B<INTERCAL> language, for its endless inspiration.
As its manual states:
"The earliest known description of the COME FROM statement in the computing
( run in 1.109 second using v1.01-cache-2.11-cpan-d8267643d1d )