There are a couple things going on here, most of which is covered in Intermediate Perl.
First, the []
braces makes an array reference, and all references are scalars. Assigning a reference to a scalar is assigning a scalar to a scalar. When you output this, you see the stringification of a reference: ARRAY(0x44444444)
. Whenever you give something to print, it stringifies itself by whatever rules that thing uses: references show their type and an internal (not physical) memory address.
Second, Perl decides how to treat the righthand side of an assignment based on what it sees in the lefthand side. In both assignments you have a scalar on the left, so Perl picks scalar semantics. In general, Perl cares more about the "verbs" than the "nouns", which is a switch from many mainstream languages which choose their operations based on what you have (the particular object identity) instead of what you are doing with it.
The tricky part here is that many people never took the time to figure out the difference between an array and a list, so there are a lot of terrible explanations out there.
So, what is this?
('111','222','aaa','bbb')
In Perl, we don't know yet because we don't have context. In human terms, that looks like a list. It has several items, it has parens around it, and outside of programming, that's what we call a list. But this is not outside of programming, and every language is very particular about some ideas such that our everyday uses of that idea doesn't translate. (Which is one of the strongest arguments to go through a tutorial for any language, not just to learn its syntax but also its basic concept).
But, back to that Perl expression, ('111','222','aaa','bbb')
. It's floating in the ether waiting for something to give it the extra context it needs.
Inside a foreach
, Perl uses list context because that's what foreach
does:
foreach my $item ( ('111','222','aaa','bbb') ) { ... }
Assigning to an array enforces a list context, because that's what it does:
my @array = ('111','222','aaa','bbb');
Creating an array reference is the same:
[ ('111','222','aaa','bbb') ]
In Perl, you have to know which context you have. That's a bit weird at first, but you get used to it.
Now, there are some things that don't use list context, and you've discovered one of those. Assigning this expression to a scalar uses scalar context, because that's what the assignment operator does when the lefthand side is a scalar:
my $s = ('111','222','aaa','bbb'); # not a list!
What does Perl do with the comma in scalar context? It does the same thing that C comma operator does. It evaluates the leftmost expression, discards the result, evaluates the righthand expression, and returns the result. In the case of several commas, that righthand result becomes the lefthand expression for the next comma. Ultimately, you end up with the evaluated expression at the end of the series.
In this example this seems silly, but consider something more complicated. Each of those sub-expressions may have side effects. In this example, each sub-expression sets the value of an existing variable:
use v5.10;
my( $dog, $cat, $bird );
say join "\n", "---Start", "Dog: $dog", "Cat: $cat", "Bird: $bird";
my $s = ( $dog = 'Snoopy', $cat = 'Garfield', $bird = 'Woody' );
say join "\n", "---End", "Dog: $dog", "Cat: $cat", "Bird: $bird";
say "\ns is $s";
The output shows that the variables get new values as a result of the comma operator in scalar context, and that the final value of $s
is the last evaluated expression in the series:
---Start
Dog:
Cat:
Bird:
---End
Dog: Snoopy
Cat: Garfield
Bird: Woody
s is Woody
This is useful in some places where Perl expects a scalar. Consider a C-style for
loop where you iterate over a single variable, and each of the three places in the construct deal with one variable. Any of those places can have side effects, that but this is how it's typically written:
for( $i = 0; $i <= 137; $i++ ) { ... }
You could also use the scalar comma to have multiple side effects in the initialization and increment sections. This is sometimes useful, especially when the block can skip or adjust the parameters:
for( $i = 0, $j = 0; $i + $j <= 137; $i++, $j++ ) { ... }
Some advice on answers
A typical answer uses the example expression (1, 2, 3)
because that's a natural one. However, it comes with an unintended confusion because it evaluates to the same thing either way, but for different reasons:
my @array = ( 1, 2, 3 );
my $s = @array; # size of array, 3
Assigning that expression to a scalar also gets 3, because that's the last thing in the series:
my $size = ( 1, 2, 3 ); # scalar comma
It's better to choose a different example so the number 3 isn't accidently the result. It would be better if the size was not an element in the array, and even better if the scalar result would not be a number. The original question did that:
('111','222','aaa','bbb');
The other answers, however, fell for this trap.
In general, for examples, choosing non-sequential or unrelated answers can elucidate the mechanics.