From 4051c94d702d31c6ee493c1479a9e25a69bf8e08 Mon Sep 17 00:00:00 2001 From: Father Chrysostomos Date: Tue, 31 May 2011 21:55:13 -0700 Subject: [PATCH] Revert "Accept lvalue subroutines as a useful feature." MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit This reverts commit c72c0c0bdd3dbc2b529b28a4f324a1cc149a6453 at Jesse’s request. --- pod/perlsub.pod | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/pod/perlsub.pod b/pod/perlsub.pod index 54f782c..81dbfa1 100644 --- a/pod/perlsub.pod +++ b/pod/perlsub.pod @@ -732,12 +732,16 @@ also accepted. =head2 Lvalue subroutines X X +B: 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 { - $val; # or "return $val;" + # return $val; this doesn't work, don't say "return" + $val; } sub nomod { $val; @@ -762,18 +766,38 @@ and in: all the subroutines are called in a list context. -Lvalue subroutines are convenient, but there are some things to keep -in mind. +=over 4 + +=item 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. -You can only return scalar lvalues. +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; -When used with objects, they violate encapsulation. A normal mutator -can check the supplied argument before setting the attribute it is -protecting, an lvalue subroutine cannot. + my $some_array_ref = []; # protected by mutators ?? -Lvalue subroutines are most valuable to contruct simple data -structures that do not require any special processing when storing and -retrieving the values. + 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 }; + +=back =head2 Passing Symbol Table Entries (typeglobs) X X<*> -- 2.7.4