Callback-Frame
view release on metacpan or search on metacpan
NAME
Callback::Frame - Preserve error handlers and "local" variables across
callbacks
SYNOPSIS
use Callback::Frame;
my $callback;
frame_try {
$callback = fub {
die "some error";
};
$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 };
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 )