Callback-Frame

 view release on metacpan or  search on metacpan

README  view on Meta::CPAN

NAME
    Callback::Frame - Preserve error handlers and "local" variables across
    callbacks

SYNOPSIS
        use Callback::Frame;

        my $callback;

        frame_try {
          $callback = fub {
                        die "some error";
                      };

README  view on Meta::CPAN

        $callback->();

    This will print something like:

        some error at tp.pl line 7.
        ----- Callback::Frame stack-trace -----
        synopsis.pl:8 - ANONYMOUS FRAME
        synopsis.pl:13 - ANONYMOUS FRAME

BACKGROUND
    When programming with callbacks in perl, you create anonymous functions
    with "sub { ... }". These functions are especially useful because when
    they are called they will preserve their surrounding lexical
    environment.

    In other words, the following bit of code

        my $callback;
        {
          my $var = 123;
          $callback = sub { $var };

README  view on Meta::CPAN

    Callback::Frame enabled code. For example, given the following AnyEvent
    statement:

        $watcher = AE::io $sock, 0, sub { do_stuff() };

    In order for the callback to have its dynamic environment maintained,
    you just need to change it to this:

        $watcher = AE::io $sock, 0, fub { do_stuff() };

    IMPORTANT NOTE: All callbacks that may be invoked outside the dynamic
    environment of the current frame should be created with "frame" or "fub"
    so that the dynamic environment will be correctly re-applied when the
    callback is invoked.

    The "frame_try" and "frame_catch" subs are equivalent to a call to
    "frame" with "code" and "catch" parameters. However, unlike with
    "frame", the frame is executed immediately.

    "frame_void" takes a single callback argument. This can be useful if you
    wish to kick off an unassociated asynchronous action while handling. If
    the action is run in void context, there is no way for it to throw an
    exception that will affect your request, or to access its local
    variables. Note that you probably should install a separate
    "frame_catch" in case the unassociated operation throws exceptions.

    Libraries that wrap callbacks in frames can use the
    "Callback::Frame::is_frame()" function to determine if a given callback
    is already wrapped in a frame. It returns true if the callback is
    wrapped in a frame and is therefore suitable for use with
    "existing_frame". Sometimes libraries like to automatically wrap a
    callback in a frame unless it already is one:

        if (!Callback::Frame::is_frame($callback)) {
          $callback = frame(code => $callback);
        }

lib/Callback/Frame.pm  view on Meta::CPAN


1;


__END__

=encoding utf-8

=head1 NAME

Callback::Frame - Preserve error handlers and "local" variables across callbacks

=head1 SYNOPSIS

    use Callback::Frame;

    my $callback;

    frame_try {
      $callback = fub {
                    die "some error";

lib/Callback/Frame.pm  view on Meta::CPAN

This will print something like:

    some error at tp.pl line 7.
    ----- Callback::Frame stack-trace -----
    synopsis.pl:8 - ANONYMOUS FRAME
    synopsis.pl:13 - ANONYMOUS FRAME


=head1 BACKGROUND

When programming with callbacks in perl, you create anonymous functions with C<sub { ... }>. These functions are especially useful because when they are called they will preserve their surrounding lexical environment.

In other words, the following bit of code

    my $callback;
    {
      my $var = 123;
      $callback = sub { $var };
    }
    print $callback->();

lib/Callback/Frame.pm  view on Meta::CPAN

C<frame> also accepts C<catch>, C<local>, C<existing_frame>, and C<name> parameters which are described below.

C<fub> simplifies the conversion of existing callback code into Callback::Frame enabled code. For example, given the following L<AnyEvent> statement:

    $watcher = AE::io $sock, 0, sub { do_stuff() };

In order for the callback to have its dynamic environment maintained, you just need to change it to this:

    $watcher = AE::io $sock, 0, fub { do_stuff() };

B<IMPORTANT NOTE>: All callbacks that may be invoked outside the dynamic environment of the current frame should be created with C<frame> or C<fub> so that the dynamic environment will be correctly re-applied when the callback is invoked.

The C<frame_try> and C<frame_catch> subs are equivalent to a call to C<frame> with C<code> and C<catch> parameters. However, unlike with C<frame>, the frame is executed immediately.

C<frame_void> takes a single callback argument. This can be useful if you wish to kick off an unassociated asynchronous action while handling. If the action is run in void context, there is no way for it to throw an exception that will affect your re...

Libraries that wrap callbacks in frames can use the C<Callback::Frame::is_frame()> function to determine if a given callback is already wrapped in a frame. It returns true if the callback is wrapped in a frame and is therefore suitable for use with C...

    if (!Callback::Frame::is_frame($callback)) {
      $callback = frame(code => $callback);
    }

If you wish to run a coderef inside an existing frame's dynamic environment, when creating a frame you can pass in an existing frame as the C<existing_frame> parameter. When this frame is executed, the C<code> of the frame will be run inside C<existi...

    frame(existing_frame => $callback, code => sub {
      die "request timed out";
    })->();



( run in 1.014 second using v1.01-cache-2.11-cpan-9b1e4054eb1 )