The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME
    returning - define subs that act like "return"

SYNOPSIS
            use Test::Simple tests => 1;
        
            use returning {
                    Yes   => 1,
                    No    => 0,
            };
        
            sub beats_sissors
            {
                    local $_ = shift;
                    No  if /paper/i;
                    Yes if /rock/i;
                    No  if /scissors/;
            }
        
            ok beats_scissors("rock");

DESCRIPTION
    The "returning" module allows you to define subs which act like
    "return". That is, they break out of their caller sub. In the SYNPOSIS
    example, the "/scissors/i" regexp is never even evaluated because the
    "Yes" statement breaks out of the the sub, returning "1". The
    "beats_scissors" function could have alternatively been written as:

            sub beats_sissors
            {
                    local $_ = shift;
                    return 0 if /paper/i;
                    return 1 if /rock/i;
                    return 0 if /scissors/;
            }

    "returning" may be especially useful for domain-specific languages.

  Usage
    There are three ways to define a returning sub using this module:

            use returning { subname => 'value' };

    This creates the sub in the caller's namespace called " subname " with
    an empty prototype. (So when calling the sub, you don't need to use
    parentheses; just like with constant subs, but without as much
    optimization.)

            use returning { subname => sub { ... } }

    This installs the provided sub into the caller's namespace. This allows
    you to define non-constant subs, including subs that take parameters and
    do interesting stuff with them.

            BEGIN {
                    sub subname { ... }
            };
            use returning 'subname'; # look, no hashref!

    This does not install any sub into the caller's namespace, but modifies
    an existing sub to act in a returning way. Note that because "use"
    operates at compile time, you need to take a lot of care to ensure that
    the sub has already been defined.

    These can be combined, a la...

            use constant ZeroButTrue => '0E0';
            use returning 'ZeroButTrue', {
                    Affirm   => !!1,
                    Deny     => !!0,
                    Mu       => sub { return; },
            }

  Implementation Notes
    My first stab at this used Devel::Declare, but I couldn't quite get it
    working, and nobody in "#devel-declare" seemed sure why it was not. It
    seems possible that the ability to do this lies slightly beyond what
    Devel::Declare is capable of.

    Instead Scope::Upper has been used to create wrappers which jump up one
    more subroutine than expected when they return. This means that some of
    the magic happens at run-time rather than compile-time, so it perhaps
    executes slightly slower, but probably compiled slightly faster.

    An advantage of Scope::Upper is that you can re-export your "returning"
    subs to other packages with no problem, and they'll continue to have
    their special behaviour with no extra effort.

    A feature I had been hoping to achieve with Devel::Declare would be for
    calling a sub with an ampersand ("&Affirm()") to act as a way of
    avoiding the magic behaviour. This has not been possible with
    Scope::Upper.

  Class Method
    "returning->setup_for($package, $subname)"
        Given the package name and subname of an *existing* sub, sets up the
        magic.

BUGS
    Please report any bugs to
    <http://rt.cpan.org/Dist/Display.html?Queue=returning>.

SEE ALSO
    "Scope::Upper" takes care of most of the black magic.

AUTHOR
    Toby Inkster <tobyink@cpan.org>.

CREDITS
    Thanks OSFAMERON, Matt S Trout (MSTROUT), and Ash Berlin (ASH), for
    helping me through some of the tricky bits.

COPYRIGHT AND LICENCE
    This software is copyright (c) 2012 by Toby Inkster.

    This is free software; you can redistribute it and/or modify it under
    the same terms as the Perl 5 programming language system itself.

DISCLAIMER OF WARRANTIES
    THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
    WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
    MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.