- publishing free software manuals
Perl Language Reference Manual
by Larry Wall and others
Paperback (6"x9"), 724 pages
ISBN 9781906966027
RRP £29.95 ($39.95)

Sales of this book support The Perl Foundation! Get a printed copy>>>

8.4 Lvalue subroutines

WARNING: Lvalue subroutines are still experimental and the implementation may change in future versions of Perl.

It is possible to return a modifiable value from a subroutine. To do this, you have to declare the subroutine to return an lvalue.

my $val;
sub canmod : lvalue {
    # return $val; this doesn't work, don't say "return"
    $val;
}
sub nomod {
    $val;
}
canmod() = 5;   # assigns to $val
nomod()  = 5;   # ERROR

The scalar/list context for the subroutine and for the right-hand side of assignment is determined as if the subroutine call is replaced by a scalar. For example, consider:

data(2,3) = get_data(3,4);

Both subroutines here are called in a scalar context, while in:

(data(2,3)) = get_data(3,4);

and in:

(data(2),data(3)) = get_data(3,4);

all the subroutines are called in a list context.

Lvalue subroutines are EXPERIMENTAL
They appear to be convenient, but there are several reasons to be circumspect. You can't use the return keyword, you must pass out the value before falling out of subroutine scope. (see comment in example above). This is usually not a problem, but it disallows an explicit return out of a deeply nested loop, which is sometimes a nice way out. They violate encapsulation. A normal mutator can check the supplied argument before setting the attribute it is protecting, an lvalue subroutine never gets that chance. Consider;
my $some_array_ref = [];    # protected by mutators ??
sub set_arr {               # normal mutator
    my $val = shift;
    die("expected array, you supplied ", ref $val)
       unless ref $val eq 'ARRAY';
    $some_array_ref = $val;
}
sub set_arr_lv : lvalue {   # lvalue mutator
    $some_array_ref;
}
# set_arr_lv cannot stop this !
set_arr_lv() = { a => 1 };
ISBN 9781906966027Perl Language Reference ManualSee the print edition