NAME

    Syntax::Keyword::Finally - add FINALLY phaser block syntax to perl

SYNOPSIS

       use Syntax::Keyword::Finally;
    
       {
          my $dbh = DBI->connect( ... ) or die "Cannot connect";
          FINALLY { $dbh->disconnect; }
    
          my $sth = $dbh->prepare( ... ) or die "Cannot prepare";
          FINALLY { $sth->finish; }
    
          ...
       }

DESCRIPTION

    This module provides a syntax plugin that implements a phaser block
    that executes its block when the containing scope has finished. The
    syntax of the FINALLY block looks similar to other phasers in perl
    (such as BEGIN), but the semantics of its execution are different.

    The operation can be considered a little similar to an END block, but
    with the following key differences:

      * A FINALLY block runs at the time that execution leaves the block it
      is declared inside, whereas an END block runs at the end time of the
      entire program regardless of its location.

      * A FINALLY block is invoked at the time its containing scope has
      finished, which means it might run again if the block is entered
      again later in the program. An END block will only ever run once.

      * A FINALLY block will only take effect if execution reaches the line
      it is declared on; if the line is not reached then nothing happens.
      An END block will always be invoked once declared, regardless of the
      dynamic extent of execution at runtime.

    FINALLY blocks are primarily intended for cases such as resource
    finalisation tasks that may be conditionally required.

    For example in the synopsis code, after normal execution the statement
    handle will be finished using the $sth->finish method, then the
    database will be disconnected with $dbh->disconnect. If instead the
    prepare method failed then the database will still be disconnected, but
    there is no need to finish with the statement handle as the second
    FINALLY block was never encountered.

KEYWORDS

 FINALLY

       FINALLY {
          STATEMENTS...
       }

    The FINALLY keyword introduces a phaser block (similar to e.g. BEGIN
    and END), which runs its code body at the time that its immediately
    surrounding code block finishes.

    When the FINALLY statement is encountered, the body of the code block
    is pushed to a queue of pending operations, which is then flushed when
    the surrounding block finishes for any reason - either by implicit
    fallthrough, or explicit termination by return, die or any of the loop
    control statements next, last or redo.

       sub f
       {
          FINALLY { say "The function has now returned"; }
          return 123;
       }

    If multiple FINALLY statements appear within the same block, they are
    pushed to the queue in LIFO order; the last one encountered is the
    first one to be executed.

       {
          FINALLY { say "This happens second"; }
          FINALLY { say "This happens first"; }
       }

    A FINALLY phaser will only take effect if the statement itself is
    actually encountered during normal execution. This is in direct
    contrast to an END phaser which always occurs. This makes it ideal for
    handling finalisation of a resource which was created on a nearby
    previous line, where the code to create it might have thrown an
    exception instead. Because the exception skipped over the FINALLY
    statement, the code body does not need to run.

       my $resource = Resource->open( ... );
       FINALLY { $resource->close; }

TODO

    This module contains a unit test file copied and edited from my core
    perl branch to provide the same syntax. Several test cases are
    currently commented out because this implementation does not yet handle
    them:

      * Ensure that FINALLY blocks can throw exceptions.

      * Complain on attempts to return, goto, or next/last/redo out of a
      FINALLY block.

AUTHOR

    Paul Evans <leonerd@leonerd.org.uk>

