There is no list context in
$c = ($a, $b);
Instead, what you are seeing is the comma operator in action:
Binary "," is the comma operator. In scalar context it evaluates its left argument, throws that value away, then evaluates its right argument and returns that value. This is just like C's comma operator.
To see this more clearly, take a look at:
#!/usr/bin/perl
use strict; use warnings;
my $x = {a => 1};
my $y = {a => 2, b => 0};
my $z = ($x, $y);
print "\$x = $x\t\$y = $y\t\$z = $z\n";
my @z = ($x, $y);
print "@z\n";
First, I used warnings. Therefore, when I run this script, I get the warning:
Useless use of private variable in void context at C:\Temp\t.pl line 7.
Always enable warnings.
Now, the output shows what's happening:
$x = HASH(0x39cbc) $y = HASH(0x39dac) $z = HASH(0x39dac)
HASH(0x39cbc) HASH(0x39dac)
Clearly, $z
refers to the same anonymous hash as does $y
. No copying of values was done.
And, $z[0]
refers to the same anonymous hash as does $x
and $z[1]
refers to the same anonymous has as do $y
and $z
.
Note that parentheses alone do not create list context. In the case of
my @z = ($x, $y);
they are necessary because =
binds more tightly than the comma operator.
my @z = $x, $y;
would assign $x
to $z[0]
and discard $y
(and emit a warning) whereas
my @z = 1 .. 5;
would work as expected.
Finally, if you wanted to assign to $z
a new anonymous hash which contains copies of the anonymous hashes to which both $x
and $y
point, you would do
#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper;
my $x = {a => 1};
my $y = {a => 2, b => 0};
my $z = { %$x, %$y };
print Dumper $z;
which would output:
$VAR1 = {
'a' => 2,
'b' => 0
};
because hash keys are, by definition, unique. If you want to preserve all values associated with the keys of both hashes, you need to do something slightly more complicated (and use anonymous arrayrefs as values in the "union" hash):
#!/usr/bin/perl
use strict; use warnings;
use Data::Dumper;
my $x = {a => 1};
my $y = {a => 2, b => 0};
my $z;
push @{ $z->{$_} }, $x->{$_} for keys %$x;
push @{ $z->{$_} }, $y->{$_} for keys %$y;
print Dumper $z;
Output:
VAR1 = {
'a' => [
1,
2
],
'b' => [
0
]
};