2013/12/10

Futures advent day 10

Day 10 - Conditional Chaining

Over the past few days we have seen uses of then and else to chain sequences of code together. Sometimes the code in a then or else block will inspect its given arguments, and decide that it doesn't in fact want to perform any other action so just returns a new Future containing the same values again.

Instead of this, we can use the methods then_with_f and else_with_f, which are variations of then and else which pass the code block the actual Future object they are invoked on in addition to the result or failure list it contains. The code can then either construct a new Future containing different results, or just return that one directly.

sub GET_checked
{
  my ( $url ) = @_;

  GET( $url )->then_with_f( sub {
    my ( $f, $resp ) = @_;

    return $f if $resp->code =~ m/^[23]../;

    return Future->new->fail($resp->code." ".$resp->message, $resp);
  });
}

This is not only neater and clearer to read, but is also more efficient because it doesn't need to create yet another Future object just to contain the same result that the one it was invoked on already had. Equally, an else_with_f can neaten up the way we sometimes simply propagate a failure if we decide not to handle it.

my $f = GET_checked("http://my-site-here.com/a-page")
  ->else_with_f( sub {
     my ( $f, $failure, $response ) = @_;

     return $f if $response->code != 500;

     return Future->new->done(
       HTTP::Response->new( 200, "OK", [],
         "Server is down, but have some fluffy kittens instead")
     );
  });

<< First | < Prev | Next >


Edit 2013/12/29: Updated for then_with_f and else_with_f

No comments:

Post a Comment