Assignable Subroutines - Page 24
July 27, 2001
Some of Perl's built-in functions allow us to assign to them as
well as use them in expressions. In programming parlance, the
result of the function is an lvalue, or a value that
can appear on the left-hand side of an assignment. The most
common and obvious lvalues are variables, which we
assign to all the time:
$scalar_value = "value";
Some Perl functions can also be assigned to in this way, for
example the substr function:
$mystring = "this is some text";
substr ($mystring, 0, 7) = "Replaced";
print $mystring; # produces "Replaced some text";
The substr function returns part of a string. If the
string happens to be held in a variable then this returned string
segment is an lvalue, and can be assigned to. Perl
does not even require that the new text be the same length, as
the above example illustrates. It would be wonderful to be able
to do this kind of thing in our own subroutines.
In fact, Perl does allow us to this, albeit only experimentally
at the moment. Assignable subroutines make use of subroutine
attributes (an experimental feature of Perl in version 5.6).
Since attributes are likely to evolve, or possibly even disappear
entirely, this technique is not guaranteed to work and should be
avoided for production code. However, for the moment, to make a
subroutine assignable we can use the special attribute
lvalue, as this simple assignable subroutine script
demonstrates:
#!/usr/bin/perl
# assignable.pl
use warnings;
use strict;
my $scalar = "Original String";
sub assignablesub : lvalue {
$scalar;
}
print $scalar, "\n";
assignablesub = "Replacement String";
print $scalar, "\n";
In order for an assignable subroutine to function correctly, it
must return a variable. In addition, it must not use
return, because with an assignable subroutine data
can pass in as well as out. Currently (as of Perl 5.6) only
scalar values may be used as assignable return values. This
includes an array element or hash value, however. Future versions
of Perl are expected to lift this restriction.
Attributes do not preclude prototypes. If we want to specify a
prototype, we can do so after the subroutine, before any
attributes. The following example shows a prototyped assignable
subroutine that provides an example of assigning to an array via
the returned lvalue.
my @array = (1, 2, 3);
sub set_element (\@$) : lvalue {
@{$_[0]} [$_[1]];
# return element of passed array
# @{$_[0]} is the array
# [$_[1]] is the $_[1]th element of that array
}
set_element (@array, 2) = 5;
In itself this is not a particularly useful example, of course,
but it may lead to some interesting possibilities.
Closures - Page 23
Professional Perl Programming
Attribute Lists - Page 25
|