This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Import perl5184delta
[perl5.git] / pod / perlref.pod
index 12e1e14..86ecfdd 100644 (file)
@@ -107,7 +107,7 @@ as using square brackets--instead it's the same as creating
 a list of references!
 
     @list = (\$a, \@b, \%c);
-    @list = \($a, @b, %c);     # same thing!
+    @list = \($a, @b, %c);      # same thing!
 
 As a special case, C<\(@foo)> returns a list of references to the contents
 of C<@foo>, not a reference to C<@foo> itself.  Likewise for C<%foo>,
@@ -122,8 +122,8 @@ A reference to an anonymous hash can be created using curly
 brackets:
 
     $hashref = {
-       'Adam'  => 'Eve',
-       'Clyde' => 'Bonnie',
+        'Adam'  => 'Eve',
+        'Clyde' => 'Bonnie',
     };
 
 Anonymous hash and array composers like these can be intermixed freely to
@@ -190,8 +190,8 @@ template without using eval().  Here's a small example of how
 closures work:
 
     sub newprint {
-       my $x = shift;
-       return sub { my $y = shift; print "$x, $y!\n"; };
+        my $x = shift;
+        return sub { my $y = shift; print "$x, $y!\n"; };
     }
     $h = newprint("Howdy");
     $g = newprint("Greetings");
@@ -297,20 +297,20 @@ and directory handles, though.)  However, if you assign the incoming
 value to a scalar instead of a typeglob as we do in the examples
 below, there's no risk of that happening.
 
-    splutter(*STDOUT);         # pass the whole glob
-    splutter(*STDOUT{IO});     # pass both file and dir handles
+    splutter(*STDOUT);          # pass the whole glob
+    splutter(*STDOUT{IO});      # pass both file and dir handles
 
     sub splutter {
-       my $fh = shift;
-       print $fh "her um well a hmmm\n";
+        my $fh = shift;
+        print $fh "her um well a hmmm\n";
     }
 
-    $rec = get_rec(*STDIN);    # pass the whole glob
+    $rec = get_rec(*STDIN);     # pass the whole glob
     $rec = get_rec(*STDIN{IO}); # pass both file and dir handles
 
     sub get_rec {
-       my $fh = shift;
-       return scalar <$fh>;
+        my $fh = shift;
+        return scalar <$fh>;
     }
 
 =back
@@ -365,7 +365,7 @@ Admittedly, it's a little silly to use the curlies in this case, but
 the BLOCK can contain any arbitrary expression, in particular,
 subscripted expressions:
 
-    &{ $dispatch{$index} }(1,2,3);     # call correct routine
+    &{ $dispatch{$index} }(1,2,3);      # call correct routine
 
 Because of being able to omit the curlies for the simple case of C<$$x>,
 people often make the mistake of viewing the dereferencing symbols as
@@ -374,10 +374,10 @@ though, you could use parentheses instead of braces.  That's not the case.
 Consider the difference below; case 0 is a short-hand version of case 1,
 I<not> case 2:
 
-    $$hashref{"KEY"}   = "VALUE";      # CASE 0
-    ${$hashref}{"KEY"} = "VALUE";      # CASE 1
-    ${$hashref{"KEY"}} = "VALUE";      # CASE 2
-    ${$hashref->{"KEY"}} = "VALUE";    # CASE 3
+    $$hashref{"KEY"}   = "VALUE";       # CASE 0
+    ${$hashref}{"KEY"} = "VALUE";       # CASE 1
+    ${$hashref{"KEY"}} = "VALUE";       # CASE 2
+    ${$hashref->{"KEY"}} = "VALUE";     # CASE 3
 
 Case 2 is also deceptive in that you're accessing a variable
 called %hashref, not dereferencing through $hashref to the hash
@@ -440,7 +440,7 @@ numerically to see whether they refer to the same location.
 X<reference, numeric context>
 
     if ($ref1 == $ref2) {  # cheap numeric compare of references
-       print "refs 1 and 2 refer to the same thing\n";
+        print "refs 1 and 2 refer to the same thing\n";
     }
 
 Using a reference as a string produces both its referent's type,
@@ -543,14 +543,14 @@ value.
 People frequently expect it to work like this.  So it does.
 
     $name = "foo";
-    $$name = 1;                        # Sets $foo
-    ${$name} = 2;              # Sets $foo
-    ${$name x 2} = 3;          # Sets $foofoo
-    $name->[0] = 4;            # Sets $foo[0]
-    @$name = ();               # Clears @foo
-    &$name();                  # Calls &foo()
+    $$name = 1;                 # Sets $foo
+    ${$name} = 2;               # Sets $foo
+    ${$name x 2} = 3;           # Sets $foofoo
+    $name->[0] = 4;             # Sets $foo[0]
+    @$name = ();                # Clears @foo
+    &$name();                   # Calls &foo()
     $pack = "THAT";
-    ${"${pack}::$name"} = 5;   # Sets $THAT::foo without eval
+    ${"${pack}::$name"} = 5;    # Sets $THAT::foo without eval
 
 This is powerful, and slightly dangerous, in that it's possible
 to intend (with the utmost sincerity) to use a hard reference, and
@@ -571,8 +571,8 @@ a symbol table, and thus are invisible to this mechanism.  For example:
     local $value = 10;
     $ref = "value";
     {
-       my $value = 20;
-       print $$ref;
+        my $value = 20;
+        print $$ref;
     }
 
 This will still print 10, not 20.  Remember that local() affects package
@@ -602,8 +602,8 @@ construct is I<not> considered to be a symbolic reference when you're
 using strict refs:
 
     use strict 'refs';
-    ${ bareword };     # Okay, means $bareword.
-    ${ "bareword" };   # Error, symbolic reference.
+    ${ bareword };      # Okay, means $bareword.
+    ${ "bareword" };    # Error, symbolic reference.
 
 Similarly, because of all the subscripting that is done using single words,
 the same rule applies to any bareword that is used for subscripting a hash.
@@ -659,7 +659,7 @@ trying to build.
 
     @colors = qw(red blue green yellow orange purple violet);
     for my $name (@colors) {
-        no strict 'refs';      # allow symbol table manipulation
+        no strict 'refs';       # allow symbol table manipulation
         *$name = *{uc $name} = sub { "<FONT COLOR='$name'>@_</FONT>" };
     }
 
@@ -804,6 +804,117 @@ 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 'refaliasing'>.  It is
+experimental, and will warn by default unless C<no warnings
+'experimental::refaliasing'> 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.
+
+Slicing operations and parentheses cause
+the right-hand side to be evaluated in
+list context:
+
+    \@array[5..7]
+    (\@array[5..7])
+    \(@array[5..7])
+    \@hash{'foo','bar'}
+    (\@hash{'foo','bar'})
+    \(@hash{'foo','bar'})
+    (\$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.