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>,
brackets:
$hashref = {
- 'Adam' => 'Eve',
- 'Clyde' => 'Bonnie',
+ 'Adam' => 'Eve',
+ 'Clyde' => 'Bonnie',
};
Anonymous hash and array composers like these can be intermixed freely to
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");
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
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
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
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,
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
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
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.
@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>" };
}
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.