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 )