Revert "Accept lvalue subroutines as a useful feature."
authorFather Chrysostomos <sprout@cpan.org>
Wed, 1 Jun 2011 04:55:13 +0000 (21:55 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Wed, 1 Jun 2011 04:55:13 +0000 (21:55 -0700)
This reverts commit c72c0c0bdd3dbc2b529b28a4f324a1cc149a6453
at Jesse’s request.

pod/perlsub.pod

index 54f782cc6160564baf070c93fdd95466ce620c5b..81dbfa1a228444a631994747f9f4466cd3ca851b 100644 (file)
@@ -732,12 +732,16 @@ also accepted.
 =head2 Lvalue subroutines
 X<lvalue> X<subroutine, lvalue>
 
+B<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 {
-       $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<typeglob> X<*>