Document lvalue references
authorFather Chrysostomos <sprout@cpan.org>
Sat, 11 Oct 2014 07:00:55 +0000 (00:00 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Sat, 11 Oct 2014 07:10:20 +0000 (00:10 -0700)
lib/feature.pm
pod/perlexperiment.pod
pod/perlop.pod
pod/perlref.pod
pod/perlsyn.pod
regen/feature.pl

index 7abbb98..3f93f23 100644 (file)
@@ -269,6 +269,29 @@ See L<perlsub/Signatures> for details.
 
 This feature is available from Perl 5.20 onwards.
 
+=head2 The 'lvalue_refs' feature
+
+B<WARNING>: This feature is still experimental and the implementation may
+change in future versions of Perl.  For this reason, Perl will
+warn when you use the feature, unless you have explicitly disabled the
+warning:
+
+    no warnings "experimental::lvalue_refs";
+
+This enables aliasing via assignment to references:
+
+    \$a = \$b; # $a and $b now point to the same scalar
+    \@a = \@b; #                     to the same array
+    \%a = \%b;
+    \&a = \&b;
+    foreach \%hash (@array_of_hash_refs) {
+        ...
+    }
+
+See L<perlref/Assigning to References> for details.
+
+This feature is available from Perl 5.22 onwards.
+
 =head1 FEATURE BUNDLES
 
 It's possible to load multiple features together, using
index 90539ea..093e887 100644 (file)
@@ -111,6 +111,18 @@ C<experimental::postderef>.
 The ticket for this feature is
 L<[perl #120162]|https://rt.perl.org:443/rt3/Ticket/Display.html?id=120162>.
 
+=item Lvalue references
+
+Introduced in Perl 5.22.0
+
+Using this feature triggers warnings in the category
+C<experimental::lvalue_refs>.
+
+The ticket for this feature is
+L<[perl #122947]|https://rt.perl.org/rt3/Ticket/Display.html?id=122947>.
+
+See also: L<perlref/Assigning to References>
+
 =item The <:win32> IO pseudolayer
 
 The ticket for this feature is
index 07bcaf9..a454dae 100644 (file)
@@ -1131,7 +1131,11 @@ The following are recognized:
                  x=
 
 Although these are grouped by family, they all have the precedence
-of assignment.
+of assignment.  These combined assignment operators can only operate on
+scalars, whereas the ordinary assignment operator can assign to arrays,
+hashes, lists and even references.  (See L<"Context"|perldata/Context>
+and L<perldata/List value constructors>, and L<perlref/Assigning to
+References>.)
 
 Unlike in C, the scalar assignment operator produces a valid lvalue.
 Modifying an assignment is equivalent to doing the assignment and
index 12e1e14..e71b7c7 100644 (file)
@@ -804,6 +804,109 @@ As with postfix array, postfix value slice dereferencing I<can> be used
 in interpolating strings (double quotes or the C<qq> operator), but only
 if the additional C<postderef_qq> L<feature> is enabled.
 
+=head1 Assigning to References
+
+Beginning in v5.22.0, the referencing operator can be assigned to.  It
+performs an aliasing operation, so that the variable name referenced on the
+left-hand side becomes an alias for the thing referenced on the right-hand
+side:
+
+    \$a = \$b; # $a and $b now point to the same scalar
+    \&foo = \&bar; # foo() now means bar()
+
+This syntax must be enabled with C<use feature 'lvalue_refs'>.  It is
+experimental, and will warn by default unless C<no warnings
+'experimental::lvalue_refs'> is in effect.
+
+These forms may be assigned to, and cause the right-hand side to be
+evaluated in scalar context:
+
+    \$scalar
+    \@array
+    \%hash
+    \&sub
+    \my $scalar
+    \my @array
+    \my %hash
+    \state $scalar # or @array, etc.
+    \our $scalar   # etc.
+    \local $scalar # etc.
+    \local our $scalar # etc.
+    \$some_array[$index]
+    \$some_hash{$key}
+    \local $some_array[$index]
+    \local $some_hash{$key}
+    condition ? \$this : \$that[0] # etc.
+
+Parentheses cause the right-hand side to be evaluated in list context:
+
+    (\$scalar)
+    \($scalar)
+    \(my $scalar)
+    \my($scalar)
+    (\@array)
+    (\%hash)
+    (\&sub)
+    \(&sub)
+    \($foo, @bar, %baz)
+    (\$foo, \@bar, \%baz)
+
+Each element on the right-hand side must be a reference to a datum of the
+right type.  Parentheses immediately surrounding an array (and possibly
+also C<my>/C<state>/C<our>/C<local>) will make each element of the array an
+alias to the corresponding scalar referenced on the right-hand side:
+
+    \(@a) = \(@b); # @a and @b now have the same elements
+    \my(@a) = \(@b); # likewise
+    \(my @a) = \(@b); # likewise
+    push @a, 3; # but now @a has an extra element that @b lacks
+    \(@a) = (\$a, \$b, \$c); # @a now contains $a, $b, and $c
+
+Combining that form with C<local> and putting parentheses immediately
+around a hash are forbidden (because it is not clear what they should do):
+
+    \local(@array) = foo(); # WRONG
+    \(%hash)       = bar(); # wRONG
+
+Assignment to references and non-references may be combined in lists and
+conditional ternary expressions, as long as the values on the right-hand
+side are the right type for each element on the left, though this may make
+for obfuscated code:
+
+    (my $tom, \my $dick, \my @harry) = (\1, \2, [1..3]);
+    # $tom is now \1
+    # $dick is now 2 (read-only)
+    # @harry is (1,2,3)
+
+    my $type = ref $thingy;
+    ($type ? $type == 'ARRAY' ? \@foo : \$bar : $baz) = $thingy;
+
+The C<foreach> loop can also take a reference constructor for its loop
+variable, though the syntax is limited to one of the following, with an
+optional C<my>, C<state>, or C<our> after the backslash:
+
+    \$s
+    \@a
+    \%h
+    \&c
+
+No parentheses are permitted.  This feature is particularly useful for
+arrays-of-arrays, or arrays-of-hashes:
+
+    foreach \my @a (@array_of_arrays) {
+        frobnicate($a[0], $a[-1]);
+    }
+
+    foreach \my %h (@array_of_hashes) {
+        $h{gelastic}++ if $h{type} == 'funny';
+    }
+
+B<CAVEAT:> Aliasing does not work correctly with closures.  If you try to
+alias lexical variables from an inner subroutine or C<eval>, the aliasing
+will only be visible within that inner sub, and will not affect the outer
+subroutine where the variables are declared.  This bizarre behavior is
+subject to change.
+
 =head1 SEE ALSO
 
 Besides the obvious documents, source code can be instructive.
index 2a5ced5..731b036 100644 (file)
@@ -469,7 +469,7 @@ X<readline> X<< <> >>
 =head2 Foreach Loops
 X<for> X<foreach>
 
-The C<foreach> loop iterates over a normal list value and sets the
+The C<foreach> loop iterates over a normal list value and sets the scalar
 variable VAR to be each element of the list in turn.  If the variable
 is preceded with the keyword C<my>, then it is lexically scoped, and
 is therefore visible only within the loop.  Otherwise, the variable is
@@ -499,6 +499,15 @@ X<splice>
 C<foreach> probably won't do what you expect if VAR is a tied or other
 special variable.   Don't do that either.
 
+As of Perl 5.22, there is an experimental variant of this loop that accepts
+a variable preceded by a backslash for VAR, in which case the items in the
+LIST must be references.  The backslashed variable will become an alias
+to each referenced item in the LIST, which must be of the correct type.
+The variable needn't be a scalar in this case, and the backslash may be
+followed by C<my>.  To use this form, you must enable the C<lvalue_refs>
+feature via C<use feature>.  (See L<feature>.  See also L<perlref/Assigning
+to References>.)
+
 Examples:
 
     for (@ary) { s/foo/bar/ }
@@ -518,6 +527,12 @@ Examples:
        print "Item: $item\n";
     }
 
+    use feature "lvalue_refs";
+    no warnings "experimental::lvalue_refs";
+    foreach \my %hash (@array_of_hash_references) {
+       # do something which each %hash
+    }
+
 Here's how a C programmer might code up a particular algorithm in Perl:
 
     for (my $i = 0; $i < @ary1; $i++) {
index 506f69a..1ffca38 100755 (executable)
@@ -584,6 +584,29 @@ See L<perlsub/Signatures> for details.
 
 This feature is available from Perl 5.20 onwards.
 
+=head2 The 'lvalue_refs' feature
+
+B<WARNING>: This feature is still experimental and the implementation may
+change in future versions of Perl.  For this reason, Perl will
+warn when you use the feature, unless you have explicitly disabled the
+warning:
+
+    no warnings "experimental::lvalue_refs";
+
+This enables aliasing via assignment to references:
+
+    \$a = \$b; # $a and $b now point to the same scalar
+    \@a = \@b; #                     to the same array
+    \%a = \%b;
+    \&a = \&b;
+    foreach \%hash (@array_of_hash_refs) {
+        ...
+    }
+
+See L<perlref/Assigning to References> for details.
+
+This feature is available from Perl 5.22 onwards.
+
 =head1 FEATURE BUNDLES
 
 It's possible to load multiple features together, using