The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.

NAME

Contextual::Return - Create context-senstive return values

VERSION

This document describes Contextual::Return version 0.1.0

SYNOPSIS

    use Contextual::Return;
    use Carp;

    sub foo {
        return
            SCALAR { 'thirty-twelve' }
            BOOL   { 1 }
            NUM    { 7*6 }
            STR    { 'forty-two' }

            LIST   { 1,2,3 }

            HASHREF   { {name => 'foo', value => 99} }
            ARRAYREF  { [3,2,1] }

            GLOBREF   { \*STDOUT }
            CODEREF   { croak "Don't use this result as code!"; }
        ;
    }

    # and later...

    if (my $foo = foo()) {
        for my $count (1..$foo) {
            print "$count: $foo is:\n"
                . "    array: @{$foo}\n"
                . "    hash:  $foo->{name} => $foo->{value}\n"
                ;
        }
        print {$foo} $foo->();
    }

DESCRIPTION

Usually, when you need to create a subroutine that returns different values in different contexts (list, scalar, or void), you write something like:

    sub get_server_status {
        my ($server_ID) = @_;

        # Acquire server data somehow...
        my %server_data = _ascertain_server_status($server_ID);

        # Return different components of that data,
        # depending on call context...
        if (wantarray()) {
            return @server_data{ qw(name uptime load users) };
        }
        if (defined wantarray()) {
            return $server_data{load};
        }
        if (!defined wantarray()) {
            carp 'Useless use of get_server_status() in void context';
            return;
        }
        else {
            croak q{Bad context! No biscuit!};
        }
    }

That works okay, but the code could certainly be more readable. In its simplest usage, this module makes that code more readable by providing three subroutines--LIST(), SCALAR(), VOID()--that are true only when the current subroutine is called in the corresponding context:

    use Contextual::Return;

    sub get_server_status {
        my ($server_ID) = @_;

        # Acquire server data somehow...
        my %server_data = _ascertain_server_status($server_ID);

        # Return different components of that data
        # depending on call context...
        if (LIST)   { return @server_data{ qw(name uptime load users) } }
        if (SCALAR) { return $server_data{load}                         }
        if (VOID)   { print "$server_data{load}\n"                      }
        else        { croak q{Bad context! No biscuit!}                 }
    }

Contextual returns

Those three subroutines can also be used in another way: as labels on a series of contextual return blocks (collectively known as a context sequence). When a context sequence is returned, it automatically selects the appropriate contextual return block for the calling context. So the previous example could be written even more cleanly as:

    use Contextual::Return;

    sub get_server_status {
        my ($server_ID) = @_;

        # Acquire server data somehow...
        my %server_data = _ascertain_server_status($server_ID);

        # Return different components of that data
        # depending on call context...
        return (
            LIST    { return @server_data{ qw(name uptime load users) } }
            SCALAR  { return $server_data{load}                         }
            VOID    { print "$server_data{load}\n"                      }
            DEFAULT { croak q{Bad context! No biscuit!}                 }
        );
    }

The context sequence automatically selects the appropriate block for each call context.

Lazy contextual return values

LIST and VOID blocks are always executed during the return statement. However, SCALAR blocks are not. Instead, in scalar contexts, returning a SCALAR block causes the subroutine to return an object that lazily evaluates that block every time a value is required.

This means that returning a SCALAR block is a convenient way to implement a subroutine with a lazy return value. For example:

    sub digest {
        return SCALAR {
            my ($text) = @_;
            md5($text);
        }
    }

    my $digest = digest($text);

    print $digest;   # md5() called only when $digest used as string

That also means that the value returned via a SCALAR block can be "active"; that is, re-evaluated every time it is used:

    sub make_counter {
        my $counter = 0;
        return SCALAR { $counter++ }
    }

    my $idx = make_counter();

    print "$idx\n";    # 0
    print "$idx\n";    # 1
    print "$idx\n";    # 2

To make this technique more self documenting, the SCALAR block has an alias: LAZY:

    sub digest {
        return LAZY {
            my ($text) = @_;
            md5($text);
        }
    }

 

Semi-lazy contextual return values

Sometimes, full repeated lazy evaluation of a scalar return value isn't what you really want. Sometimes what you really want is for the return value to be lazily evaluated once (the first time it's used), and then for that first value to be reused whenever the return value is subsequently reevaluated.

To get that behaviour, you can use the FIXED modifier, which causes the return value to morph itself into the actual value the first time it is used. For example:

    sub lazy {
        return
            SCALAR { 42 }
            ARRAYREF { [ 1, 2, 3 ] }
        ;
    }

    my $lazy = lazy();
    print $lazy + 1;          # 43
    print "@{$lazy}";         # 1 2 3


    sub semilazy {
        return FIXED
            SCALAR { 42 }
            ARRAYREF { [ 1, 2, 3 ] }
        ;
    }

    my $semi = semilazy();
    print $semi + 1;          # 43
    print "@{$semi}";         # die q{Can't use string ("42") as an ARRAY ref}

Finer distinctions of scalar context

Because the scalar values returned from a context sequence are lazily evaluated, it becomes possible to be more specific about what kind of scalar value should be returned: a boolean, a number, or a string. To support those distinctions, Contextual::Return provides three extra context blocks: BOOL, NUM, and STR:

    sub get_server_status {
        my ($server_ID) = @_;

        # Acquire server data somehow...
        my %server_data = _ascertain_server_status($server_ID);

        # Return different components of that data
        # depending on call context...
        return (
               LIST { @server_data{ qw(name uptime load users) }  }
               BOOL { $server_data{uptime} > 0                    }
                NUM { $server_data{load}                          }
                STR { "$server_data{name}: $server_data{uptime}"  }
               VOID { print "$server_data{load}\n"                }
            DEFAULT { croak q{Bad context! No biscuit!}           }
        );
    }

With these in place, the object returned from a scalar-context call to get_server_status() now behaves differently, depending on how it's used. For example:

    if ( my $status = get_server_status() ) {  # True if uptime > 0
        $load_distribution[$status]++;         # Evaluates to load value
        print "$status\n";                     # Prints name: uptime
    }

Referential contexts

The other major kind of scalar return value is a reference. Contextual::Return provides context blocks that allow you to specify what to (lazily) return when the return value of a subroutine is used as a reference to a scalar (SCALARREF {...}), to an array (ARRAYREF {...}), to a hash (HASHREF {...}), to a subroutine (CODEREF {...}), or to a typeglob (GLOBREF {...}).

For example, the server status subroutine shown earlier could be extended to allow it to return a hash reference, thereby supporting "named return values":

    sub get_server_status {
        my ($server_ID) = @_;

        # Acquire server data somehow...
        my %server_data = _ascertain_server_status($server_ID);

        # Return different components of that data
        # depending on call context...
        return (
               LIST { @server_data{ qw(name uptime load users) }  }
               BOOL { $server_data{uptime} > 0                    }
                NUM { $server_data{load}                          }
                STR { "$server_data{name}: $server_data{uptime}"  }
               VOID { print "$server_data{load}\n"                }
            HASHREF { return \%server_data                        }
            DEFAULT { croak q{Bad context! No biscuit!}           }
        );
    }

    # and later...

    my $users = get_server_status->{users};


    # or, lazily...

    my $server = get_server_status();

    print "$server->{name} load = $server->{load}\n";

Interpolative referential contexts

The SCALARREF {...} and ARRAYREF {...} context blocks are especially useful when you need to interpolate a subroutine into strings. For example, if you have a subroutine like:

    sub get_todo_tasks {
        return (
            SCALAR { scalar @todo_list }      # How many?
            LIST   { @todo_list        }      # What are they?
        );
    }

    # and later...

    print "There are ", scalar(get_todo_tasks()), " tasks:\n",
          get_todo_tasks();

then you could make it much easier to interpolate calls to that subroutine by adding:

    sub get_todo_tasks {
        return (
            SCALAR { scalar @todo_list }      # How many?
            LIST   { @todo_list        }      # What are they?

            SCALARREF { \scalar @todo_list }  # Ref to how many
            ARRAYREF  { \@todo_list        }  # Ref to them
        );
    }

    # and then...

    print "There are ${get_todo_tasks()} tasks:\n@{get_todo_tasks()}";

In fact, this behaviour is so useful that it's the default. If you don't provide an explicit SCALARREF {...} block, Contextual::Return automatically provides an implicit one that simply returns a reference to whatever would have been returned in scalar context. Likewise, if no ARRAYREF {...} block is specified, the module supplies one that returns the list-context return value wrapped up in an array reference.

So, in fact, you could just write:

    sub get_todo_tasks {
        return (
            SCALAR { scalar @todo_list }      # How many?
            LIST   { @todo_list        }      # What are they?
        );
    }

    # and still do this...

    print "There are ${get_todo_tasks()} tasks:\n@{get_todo_tasks()}";

Fallback contexts

As the previous sections imply, the BOOL {...}, NUM {...}, STR {...}, and various *REF {...} blocks, are special cases of the general SCALAR {...} context block. If a subroutine is called in one of these specialized contexts but does not use the corresponding context block, then the more general SCALAR {...} block is used instead (if it has been specified).

So, for example:

    sub read_value_from {
        my ($fh) = @_;

        my $value = <$fh>;
        chomp $value;

        return (
            BOOL   { defined $value }
            SCALAR { $value         }
        );
    }

ensures that the read_value_from() subroutine returns true in boolean contexts if the read was successful. But, because no specific NUM {...} or STR {...} return behaviours were specified, the subroutine falls back on using its generic SCALAR {...} block in all other scalar contexts.

Another way to think about this behaviour is that the various kinds of scalar context blocks form a hierarchy:

    SCALAR
       ^
       |
       |--< BOOL
       |
       |--< NUM
       |
       `--< STR

Contextual::Return uses this hierarchical relationship to choose the most specific context block available to handle any particular return context, working its way up the tree from the specific type it needs, to the more general type, if that's all that is available.

There are two slight complications to this picture. The first is that Perl treats strings and numbers as interconvertable so the diagram (and the Contextual::Return module) also has to allow these interconversions as a fallback strategy:

    SCALAR
       ^
       |
       |--< BOOL
       |
       |--< NUM
       |    : ^
       |    v :
       `--< STR

The dotted lines are meant to indicate that this intraconversion is secondary to the main hierarchical fallback. That is, in a numeric context, a STR {...} block will only be used if there is no NUM {...} block and no SCALAR {...} block. In other words, the generic context type is always used in preference to string<->number conversion.

The second slight complication is that the above diagram only shows a small part of the complete hierarchy of contexts supported by Contextual::Return. The full fallback hierarchy (including dotted interconversions) is:

    DEFAULT
       ^
       |
       |--< VOID
       |
       `--< NONVOID
               ^
               |
               |--< VALUE <..............
               |      ^                 :
               |      |                 :
               |      |--< SCALAR <.....:..
               |      |       ^           :
               |      |       |           :
               |      |       |--< BOOL   :
               |      |       |           :
               |      |       |--< NUM <..:..
               |      |       |    : ^      :
               |      |       |    v :      :
               |      |       `--< STR <....:..
               |      |                       :
               |      |                      .:
               |      `--< LIST ............. :
               |            : ^               :
               |            : :               :
               `--- REF     : :               :
                     ^      : :               :
                     |      v :               :
                     |--< ARRAYREF            :
                     |                       .
                     |--< SCALARREF ......... 
                     |
                     |--< HASHREF
                     |
                     |--< CODEREF
                     |
                     |--< GLOBREF
                     |
                     `--< OBJREF

As before, each dashed arrow represents a fallback relationship. That is, if the required context specifier isn't available, the arrows are followed until a more generic one is found. The dotted arrows again represent the interconversion of return values, which is attempted only after the normal hierarchical fallback fails.

In other words, if a subroutine is called in a context that expects a scalar reference, but no SCALARREF {...} block is provided, then Contextual::Return tries the following blocks in order:

        REF {...}
    NONVOID {...}
    DEFAULT {...}
        STR {...} (automatically taking a reference to the result)
        NUM {...} (automatically taking a reference to the result)
     SCALAR {...} (automatically taking a reference to the result)
      VALUE {...} (automatically taking a reference to the result)

Likewise, in a list context, if there is no LIST {...} context block, the module tries:

       VALUE {...}
     NONVOID {...}
     DEFAULT {...}
    ARRAYREF {...} (automatically dereferencing the result)
         STR {...} (treating it as a list of one element)
         NUM {...} (treating it as a list of one element)
      SCALAR {...} (treating it as a list of one element)

The more generic context blocks are especially useful for intercepting unexpected and undesirable call contexts. For example, to turn off the automatic scalar-ref and array-ref interpolative behaviour described in "Interpolative referential contexts", you could intercept all referential contexts using a generic REF {...} context block:

    sub get_todo_tasks {
        return (
            SCALAR { scalar @todo_list }      # How many?
            LIST   { @todo_list        }      # What are they?

            REF { croak q{get_todo_task() can't be used as a reference} }
        );
    }

    print 'There are ', get_todo_tasks(), '...';    # Still okay
    print "There are ${get_todo_tasks()}...";       # Throws an exception

    

Failure contexts

Two of the most common ways to specify that a subroutine has failed are to return a false value, or to throw an exception. The Contextual::Return module provides a mechanism that allows the subroutine writer to support both of these mechanisms at the same time, by using the FAIL specifier.

A return statement of the form:

    return FAIL;

causes the surrounding subroutine to return undef (i.e. false) in boolean contexts, and to throw an exception in any other context. For example:

    use Contextual::Return;

    sub get_next_val {
        my $next_val = <>;
        return FAIL if !defined $next_val;
        chomp $next_val;
        return $next_val;
    }

If the return FAIL statement is executed, it will either return false in a boolean context:

    if (my $val = get_next_val()) {    # returns undef if no next val
        print "[$val]\n";
    }

or else throw an exception if the return value is used in any other context:

    print get_next_val();       # throws exception if no next val

    my $next_val = get_next_val();
    print "[$next_val]\n";      # throws exception if no next val

The exception that is thrown is of the form:

    Call to main::get_next_val() failed at demo.pl line 42

but you can change that message by providing a block to the FAIL, like so:

    return FAIL { "No more data" } if !defined $next_val;

in which case, the final value of the block becomes the exception message:

    No more data at demo.pl line 42

Configurable failure contexts

The default FAIL behaviour--false in boolean context, fatal in all others--works well in most situations, but violates the Platinum Rule ("Do unto others as they would have done unto them").

So it may be user-friendlier if the user of a module is allowed decide how the module's subroutines should behave on failure. For example, one user might prefer that failing subs always return undef; another might prefer that they always throw an exception; a third might prefer that they always log the problem and return a special Failure object; whilst a fourth user might want to get back 0 in scalar contexts, an empty list in list contexts, and an exception everywhere else.

You could create a module that allows the user to specify all these alternatives, like so:

    package MyModule;
    use Contextual::Return;
    use Log::StdLog;

    sub import {
        my ($package, @args) = @_;

        Contextual::Return::FAIL_WITH {
            ':false' => sub { return undef },
            ':fatal' => sub { croak @_     },
            ':filed' => sub {
                            print STDLOG 'Sub ', (caller 1)[3], ' failed';
                            return Failure->new();
                        },
            ':fussy' => sub {
                            SCALAR  { undef    }
                            LIST    { ()       }
                            DEFAULT { croak @_ }
                        },
        } @args;
    }

This configures Contextual::Return so that, instead of the usual false-or-fatal semantics, every return FAIL within MyModule's namespace is implemented by one of the four subroutines specified in the hash that was passed to FAIL_WITH.

Which of those four subs implements the FAIL is determined by the arguments passed after the hash (i.e. by the contents of @args). FAIL_WITH walks through that list of arguments and compares them against the keys of the hash. If a key matches an argument, the corresponding value is used as the implementation of FAIL. Note that, if subsequent arguments also match a key, their subroutine overrides the previously installed implementation, so only the final override has any effect. Contextual::Return generates warnings when multiple overrides are specified.

All of which mean that, if a user loaded the MyModule module like this:

    use MyModule qw( :fatal other args here );

then every FAIL within MyModule would be reconfigured to throw an exception in all circumstances, since the presence of the ':fatal' in the argument list will cause FAIL_WITH to select the hash entry whose key is ':fatal'.

On the other hand, if they loaded the module:

    use MyModule qw( :fussy other args here );

then each FAIL within MyModule would return undef or empty list or throw an exception, depending on context, since that's what the subroutine whose key is ':fussy' does.

Many people prefer module interfaces with a flag = value> format, and FAIL_WITH supports this too. For example, if you wanted your module to take a -fail flag, whose associated value could be any of "undefined", "exception", "logged", or "context", then you could implement that simply by specifying the flag as the first argument (i.e. before the hash) like so:

    sub import {
        my $package = shift;

        Contextual::Return::FAIL_WITH -fail => {
            'undefined' => sub { return undef },
            'exception' => sub { croak @_     },
            'logged'    => sub {
                            print STDLOG 'Sub ', (caller 1)[3], ' failed';
                            return Failure->new();
                        },
            'context'   => sub {
                            SCALAR  { undef    }
                            LIST    { ()       }
                            DEFAULT { croak @_ }
                        },
        } @_;

and then load the module:

    use MyModule qw( other args here ), -fatal=>'undefined';

or:

    use MyModule qw( other args here ), -fatal=>'exception';

I this case, FAIL_WITH scans the argument list for a pair of values: it's flag string, followed by some other selector value. Then it looks up the selector value in the hash, and installs the corresponding subroutine as its local FAIL handler.

If this "flagged" interface is used, the user of the module can also specify their own handler directly, by passing a subroutine reference as the selector value instead of a string:

    use MyModule qw( other args here ), -fatal=>sub{ die 'horribly'};

If this last example were used, any call to FAIL within MyModule would invoke the specified anonymous subroutine (and hence throw a 'horribly' exception).

Note that, any overriding of a FAIL handler is specific to the namespace and file from which the subroutine that calls FAIL_WITH is itself called. Since FAIL_WITH is designed to be called from within a module's import() subroutine, that generally means that the FAILs within a given module X are only overridden for the current namespace within the particular file from module X is loaded. This means that two separate pieces of code (in separate files or separate namespaces) can each independently overide a module's FAIL behaviour, without interfering with each other.

Lvalue contexts

Recent versions of Perl offer (limited) support for lvalue subroutines: subroutines that return a modifiable variable, rather than a simple constant value.

Contextual::Return can make it easier to create such subroutines, within the limitations imposed by Perl itself. The limitations that Perl places on lvalue subs are:

  1. The subroutine must be declared with an :lvalue attribute:

        sub foo :lvalue {...}
  2. The subroutine must not return via an explicit return. Instead, the last statement must evaluate to a variable, or must be a call to another lvalue subroutine call.

        my ($foo, $baz);
    
        sub foo :lvalue {
            $foo;               # last statement evals to a var
        }
    
        sub bar :lvalue {
            foo();              # last statement is lvalue sub call
        }
    
        sub baz :lvalue {
            my ($arg) = @_;
    
            $arg > 0            # last statement evals...
                ? $baz          #   ...to a var
                : bar();        #   ...or to an lvalue sub call
        }

Thereafter, any call to the lvalue subroutine produces a result that can be assigned to:

    baz(0) = 42;            # same as: $baz = 42

    baz(1) = 84;            # same as:                bar() = 84 
                            #  which is the same as:  foo() = 84
                            #   which is the same as: $foo  = 84

Ultimately, every lvalue subroutine must return a scalar variable, which is then used as the lvalue of the assignment (or whatever other lvalue operation is applied to the subroutine call). Unfortunately, because the subroutine has to return this variable before the assignment can take place, there is no way that a normal lvalue subroutine can get access to the value that will eventually be assigned to its return value.

This is occasionally annoying, so the Contextual::Return module offers a solution: in addition to all the context blocks described above, it provides three special context blocks specifically for use in lvalue subroutines: LVALUE, RVALUE, and NVALUE.

Using these blocks you can specify what happens when an lvalue subroutine is used in lvalue and non-lvalue (rvalue) context. For example:

    my $verbosity_level = 1;

    # Verbosity values must be between 0 and 5...
    sub verbosity :lvalue {
        LVALUE { $verbosity_level = max(0, min($_, 5)) }
        RVALUE { $verbosity_level                      }
    }

The LVALUE block is executed whenever verbosity is called as an lvalue:

    verbosity() = 7;

The block has access to the value being assigned, which is passed to it as $_. So, in the above example, the assigned value of 7 would be aliased to $_ within the LVALUE block, would be reduced to 5 by the "min-of-max" expression, and then assigned to $verbosity_level.

(If you need to access the caller's $_, it's also still available: as $CALLER::_.)

When the subroutine isn't used as an lvalue:

    print verbosity();
    

the RVALUE block is executed instead and its final value returned. Within an RVALUE block you can use any of the other features of Contextual::Return. For example:

    sub verbosity :lvalue {
        LVALUE { $verbosity_level = int max(0, min($_, 5)) }
        RVALUE {
            NUM  { $verbosity_level               }
            STR  { $description[$verbosity_level] }
            BOOL { $verbosity_level > 2           }
        }
    }

but the context sequence must be nested inside an RVALUE block.

You can also specify what an lvalue subroutine should do when it is used neither as an lvalue nor as an rvalue (i.e. in void context), by using an NVALUE block:

    sub verbosity :lvalue {
        my ($level) = @_;

        NVALUE { $verbosity_level = int max(0, min($level, 5)) }
        LVALUE { $verbosity_level = int max(0, min($_,     5)) }
        RVALUE {
            NUM  { $verbosity_level               }
            STR  { $description[$verbosity_level] }
            BOOL { $verbosity_level > 2           }
        }
    }

In this example, a call to verbosity() in void context sets the verbosity level to whatever argument is passed to the subroutine:

    verbosity(1);

Note that you cannot get the same effect by nesting a VOID block within an RVALUE block:

        LVALUE { $verbosity_level = int max(0, min($_, 5)) }
        RVALUE {
            NUM  { $verbosity_level               }
            STR  { $description[$verbosity_level] }
            BOOL { $verbosity_level > 2           }
            VOID { $verbosity_level = $level      }    # Wrong!
        }

That's because, in a void context the return value is never evaluated, so it is never treated as an rvalue, which means the RVALUE block never executes.

INTERFACE

Context tests

LIST()

Returns true if the current subroutine was called in list context. A cleaner way of writing: wantarray()

SCALAR()

Returns true if the current subroutine was called in scalar context. A cleaner way of writing: defined wantarray() && ! wantarray()

VOID()

Returns true if the current subroutine was called in void context. A cleaner way of writing: !defined wantarray()

NONVOID()

Returns true if the current subroutine was called in list or scalar context. A cleaner way of writing: defined wantarray()

Standard contexts

LIST {...}

The block specifies what the context sequence should evaluate to when called in list context.

SCALAR {...}

The block specifies what the context sequence should evaluate to in scalar contexts, unless some more-specific specifier scalar context specifier (see below) also occurs in the same context sequence.

VOID {...}

The block specifies what the context sequence should do when called in void context.

Scalar value contexts

BOOL {...}

The block specifies what the context sequence should evaluate to when treated as a boolean value.

NUM {...}

The block specifies what the context sequence should evaluate to when treated as a numeric value.

STR {...}

The block specifies what the context sequence should evaluate to when treated as a string value.

LAZY {...}

Another name for SCALAR {...}. Usefully self-documenting when the primary purpose of the contextual return is to defer evaluation of the return value until it's actually required.

Scalar reference contexts

SCALARREF {...}

The block specifies what the context sequence should evaluate to when treated as a reference to a scalar.

ARRAYREF {...}

The block specifies what the context sequence should evaluate to when treated as a reference to an array.

HASHREF {...}

The block specifies what the context sequence should evaluate to when treated as a reference to a hash.

Note that a common error here is to write:

    HASHREF { a=>1, b=>2, c=>3 }

The curly braces there are a block, not a hash constructor, so the block doesn't return a hash reference and the interpreter throws an exception. What's needed is:

    HASHREF { {a=>1, b=>2, c=>3} }

in which the inner braces are a hash constructor.

CODEREF {...}

The block specifies what the context sequence should evaluate to when treated as a reference to a subroutine.

GLOBREF {...}

The block specifies what the context sequence should evaluate to when treated as a reference to a typeglob.

OBJREF {...}

The block specifies what the context sequence should evaluate to when treated as a reference to an object.

Generic contexts

VALUE {...}

The block specifies what the context sequence should evaluate to when treated as a non-referential value (as a boolean, numeric, string, scalar, or list). Only used if there is no more-specific value context specifier in the context sequence.

REF {...}

The block specifies what the context sequence should evaluate to when treated as a reference of any kind. Only used if there is no more-specific referential context specifier in the context sequence.

NONVOID {...}

The block specifies what the context sequence should evaluate to when used in a non-void context of any kind. Only used if there is no more-specific context specifier in the context sequence.

DEFAULT {...}

The block specifies what the context sequence should evaluate to when used in a void or non-void context of any kind. Only used if there is no more-specific context specifier in the context sequence.

Failure context

FAIL

This block is executed unconditionally and is used to indicate failure. In a Boolean context it return false. In all other contexts it throws an exception consisting of the final evaluated value of the block.

That is, using FAIL:

    return
        FAIL { "Could not defenestrate the widget" }

is exactly equivalent to writing:

    return
           BOOL { 0 }
        DEFAULT { croak "Could not defenestrate the widget" }

except that the reporting of errors is a little smarter under FAIL.

If FAIL is called without specifying a block:

    return FAIL;

it is equivalent to:

    return FAIL { croak "Call to <subname> failed" }

(where <subname> is replaced with the name of the surrounding subroutine).

Note that, because FAIL implicitly covers every possible return context, it cannot be chained with other context specifiers.

Contextual::Return::FAIL_WITH

This subroutine is not exported, but may be called directly to reconfigure FAIL behaviour in the caller's namespace.

The subroutine is called with an optional string (the flag), followed by a mandatory hash reference (the configurations hash), followed by a list of zero-or-more strings (the selector list). The values of the configurations hash must all be subroutine references.

If the optional flag is specified, FAIL_WITH searches the selector list looking for that string, then uses the following item in the selector list as its selector value. If that selector value is a string, FAIL_WITH looks up that key in the hash, and installs the corresponding subroutine as the namespace's FAIL handler (an exception is thrown if the selector string is not a valid key of the configurations hash). If the selector value is a subroutine reference, FAIL_WITH installs that subroutine as the FAIL handler.

If the optional flag is not specified, FAIL_WITH searches the entire selector list looking for the last element that matches any key in the configurations hash. It then looks up that key in the hash, and installs the corresponding subroutine as the namespace's FAIL handler.

See "Configurable failure contexts" for examples of using this feature.

Lvalue contexts

LVALUE

This block is executed when the result of an :lvalue subroutine is assigned to. The assigned value is passed to the block as $_. To access the caller's $_ value, use $CALLER::_.

RVALUE

This block is executed when the result of an :lvalue subroutine is used as an rvalue. The final value that is evaluated in the black becomes the rvalue.

NVALUE

This block is executed when an :lvalue subroutine is evaluated in void context.

Modifiers

FIXED

This specifies that the scalar value will only be evaluated once, the first time it is used, and that the value will then morph into that evaluated value.

DIAGNOSTICS

Can't call %s in %s context";

The subroutine you called uses a contextual return, but doesn't specify what to return in the particular context in which you called it. You either need to change the context in which you're calling the subroutine, or else add a context block corresponding to the offending context (or perhaps a DEFAULT {...} block).

%s can't return a %s reference";

You called the subroutine in a context that expected to get back a reference of some kind but the subroutine didn't specify the corresponding SCALARREF, ARRAYREF, HASHREF, CODEREF, GLOBREF, or generic REF, NONVOID, or DEFAULT handlers. You need to specify the appropriate one of these handlers in the subroutine.

Can't call method '%s' on %s value returned by %s";

You called the subroutine and then tried to call a method on the return value, but the subroutine returned a classname or object that doesn't have that method. This probably means that the subroutine didn't return the classname or object you expected. Or perhaps you need to specify an OBJREF {...} context block.

Can't install two %s handlers

You attempted to specify two context blocks of the same name in the same return context, which is ambiguous. For example:

    sub foo: lvalue {
        LVALUE { $foo = $_ }
        RVALUE { $foo }
        LVALUE { $foo = substr($_,1,10) }
    }

or:

    sub bar {
        return
            BOOL { 0 }
             NUM { 1 }
             STR { "two" }
            BOOL { 1 };
    }

Did you cut-and-paste wrongly, or mislabel one of the blocks?

Expected a %s block after the %s block but found instead: %s

If you specify any of LVALUE, RVALUE, or NVALUE, then you can only specify LVALUE, RVALUE, or NVALUE blocks in the same return context. If you need to specify other contexts (like BOOL, or STR, or REF, etc.), put them inside an RVALUE block. See "Lvalue contexts" for an example.

Call to %s failed at %s.

This is the default exception that a FAIL throws in a non-scalar context. Which means that the subroutine you called has signalled failure by throwing an exception, and you didn't catch that exception. You should either put the call in an eval {...} block or else call the subroutine in boolean context instead.

Call to %s failed at %s. Failure value used at %s

This is the default exception that a FAIL throws when a failure value is captured in a scalar variable and later used in a non-boolean context. That means that the subroutine you called must have failed, and you didn't check the return value for that failure, so when you tried to use that invalid value it killed your program. You should either put the original call in an eval {...} or else test the return value in a boolean context and avoid using it if it's false.

Usage: FAIL_WITH $flag_opt, \%selector, @args

The FAIL_WITH subroutine expects an optional flag, followed by a reference to a configuration hash, followed by a list or selector arguments. You gave it something else. See "Configurable Failure Contexts".

Selector values must be sub refs

You passed a configuration hash to FAIL_WITH that specified non- subroutines as possible FAIL handlers. Since non-subroutines can't possibly be handlers, maybe you forgot the sub keyword somewhere?

Invalid option: %s => %s

The FAIL_WITH subroutine was passed a flag/selector pair, but the selector was not one of those allowed by the configuration hash.

FAIL handler for package %s redefined

A warning that the FAIL handler for a particular package was reconfigured more than once. Typically that's because the module was loaded in two places with difference configurations specified. You can't reasonably expect two different sets of behaviours from the one module within the one namespace.

CONFIGURATION AND ENVIRONMENT

Contextual::Return requires no configuration files or environment variables.

DEPENDENCIES

Requires version.pm and Want.pm.

INCOMPATIBILITIES

None reported.

BUGS AND LIMITATIONS

No bugs have been reported.

AUTHOR

Damian Conway <DCONWAY@cpan.org>

LICENCE AND COPYRIGHT

Copyright (c) 2005-2006, Damian Conway <DCONWAY@cpan.org>. All rights reserved.

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

DISCLAIMER OF WARRANTY

BECAUSE THIS SOFTWARE IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION.

IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE SOFTWARE AS PERMITTED BY THE ABOVE LICENCE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.