Toby Inkster > returning-0.002 > returning

Download:
returning-0.002.tar.gz

Dependencies

Annotate this POD

Website

CPAN RT

Open  0
View/Report Bugs
Module Version: 0.002   Source  

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.

syntax highlighting: