Acme-Sort-Sleep

 view release on metacpan or  search on metacpan

local/lib/perl5/Future/Phrasebook.pod  view on Meta::CPAN


=head1 SEQUENCING

The simplest example of a sequencing operation is simply running one piece of
code, then immediately running a second. In call/return code we can just place
one after the other.

 FIRST();
 SECOND();

Using a Future it is necessary to await the result of the first C<Future>
before calling the second.

 my $f = F_FIRST()
    ->then( sub { F_SECOND(); } );

Here, the anonymous closure is invoked once the C<Future> returned by
C<F_FIRST()> succeeds. Because C<then> invokes the code block only if the
first Future succeeds, it shortcircuits around failures similar to the way that
C<die()> shortcircuits around thrown exceptions. A C<Future> representing the
entire combination is returned by the method.

Because the C<then> method itself returns a C<Future> representing the
overall operation, it can itself be further chained.

 FIRST();
 SECOND();
 THIRD();

Z<>

 my $f = F_FIRST()
    ->then( sub { F_SECOND(); } )
    ->then( sub { F_THIRD(); } );

See below for examples of ways to handle exceptions.

=head2 Passing Results

Often the result of one function can be passed as an argument to another
function.

 OUTER( INNER() );

The result of the first C<Future> is passed into the code block given to the
C<then> method.

 my $f = F_INNER()
    ->then( sub { F_OUTER( @_ ) } );

=head1 CONDITIONALS

It may be that the result of one function call is used to determine whether or
not another operation is taken.

 if( COND() == $value ) {
    ACTION();
 }

Because the C<then_with_f> code block is given the first future in addition to
its results it can decide whether to call the second function to return a new
future, or simply return the one it was given.

 my $f = F_COND()
    ->then_with_f( sub {
       my ( $f_cond, $result ) = @_;
       if( $result == $value ) {
          return F_ACTION();
       }
       else {
          return $f_cond;
       }
    });

=head1 EXCEPTION HANDLING

In regular call/return style code, if any function throws an exception, the
remainder of the block is not executed, the containing C<try> or C<eval> is
aborted, and control is passed to the corresponding C<catch> or line after the
C<eval>.

 try {
    FIRST();
 }
 catch {
    my $e = $_;
    ERROR( $e );
 };

The C<else> method on a C<Future> can be used here. It behaves similar to
C<then>, but is only invoked if the initial C<Future> fails; not if it
succeeds.

 my $f = F_FIRST()
    ->else( sub { F_ERROR( @_ ); } );

Alternatively, the second argument to the C<then> method can be applied, which
is invoked only on case of failure.

 my $f = F_FIRST()
    ->then( undef, sub { F_ERROR( @_ ); } );

Often it may be the case that the failure-handling code is in fact immediate,
and doesn't return a C<Future>. In that case, the C<else> code block can
return an immediate C<Future> instance.

 my $f = F_FIRST()
    ->else( sub {
       ERROR( @_ );
       return Future->done;
    });

Sometimes the failure handling code simply needs to be aware of the failure,
but rethrow it further up.

 try {
    FIRST();
 }
 catch {
    my $e = $_;
    ERROR( $e );



( run in 2.064 seconds using v1.01-cache-2.11-cpan-ceb78f64989 )