The lvalue Attribute
It is possible to return a modifiable scalar value from a subroutine, but only if you declare the subroutine to return an lvalue:
my $val;
sub canmod : lvalue {
$val;
}
sub nomod {
$val;
}
canmod() = 5; # Assigns to $val.
nomod() = 5; # ERRORIf you’re passing parameters to an lvalued subroutine, you’ll usually want parentheses to disambiguate what’s being assigned:
canmod $x = 5; # assigns 5 to $x first! canmod 42 = 5; # can't change a constant; compile–time error canmod($x) = 5; # this is ok canmod(42) = 5; # and so is this
If you want to be sneaky, you can get around this in the
particular case of a subroutine that takes one argument. Declaring
the function with a prototype of ($) causes the function to be parsed with
the precedence of a named unary operator. Since named unaries have
higher precedence than assignment, you no longer need the
parentheses. (Whether this is desirable or not is left up to the
style police.)
You don’t have to be sneaky in the particular case of a
subroutine that allows zero arguments (that is, with a () prototype). Without ambiguity, you can
say this:
canmod = 5;
That works because no valid term begins with =. Similarly, lvalued method calls can
omit the parentheses when you don’t pass any arguments:
$obj–>canmod = 5;
We promise not to break those two constructs in future versions of Perl 5. They’re handy when you want to wrap object attributes in method calls (so that they can be inherited like method calls but accessed like variables). ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access