This article is compiled from a question about Perl scalar context and list contexts, explaining why in some cases, using a "list" in a scalar context does not give you the number of elements you want, and how to get the results you expect.
1. "List" does not necessarily get the number of elements in a scalar context
Perhaps you think the title is a bit strange: as defined by the Perl context, the list is given the number of list elements in the scalar context. Simply by this logic, the following statement seems to allow $scalar to be assigned a value of 3:
$scalar = qw/a b c/;
However, Perl always gives you a big surprise in some humble places, and if you print the value of $scalar, you will find that you get "C" instead of "3".
2. Why can the context rule called truth "fail"?
It seems to be a lot easier for non-Perl programmers to explain the problem. In order to understand why the context rules are "invalidated" here, we must throw away the "list of elements in a scalar context" that seems to be the truth of the conclusion, and from the language itself to look at the problem.
That's still the statement.
$scalar = qw/a b c/;
all QW operators in Perl are expanded into List form, so this statement is exactly equivalent to the next:
$scalar = (' A ', ' B ', ' C ',);
Of course, these two statements will assign the $scalar to "C".
Let's forget about the contextual rules and see what Perl sees here in Perl's eyes:
1. The assignment number is followed by an opening parenthesis, and the parentheses are a precedence constraint, and the expressions in parentheses are evaluated first.
2. The parentheses are a comma-separated expression, so it is a comma-expression, of course.
3. The value of the comma expression is the value of the last expression, and the last expression is ' C ', and its value is ' C '.
4. So the value of the entire comma expression is ' C '
5. Assign the ' C ' value to $scalar.
This is what Perl's eyes see, and why $scalar is assigned the value of ' C '.
So give you a statement:
$scalar = scalar qw/a b c/;
If you start to look at the code in Perl's eyes, you'll see that the above statement is equivalent to the Next statement:
$scalar = Scalar ' C ';
of course, what you get is still "C" rather than "3".
3. Is the Perl truth we are familiar with a fallacy?
There is a credo for Perl programmers: Context rules are absolute truths. because this rule is Perl's way of thinking, the correctness of the doubt.
Of course, this truth is still valid in the above statement.
The illusion that contextual rules are invalidated is because we tend to look at code in our own eyes rather than in Perl's eyes. Just before explaining why $scalar got ' C ', we also indirectly expressed the fact that in the statement
$scalar = qw/a b c/; $scalar = (' A ', ' B ', ' C ',); $scalar = scalar qw/a b c/;
even the statement
$scalar = scalar (' A ', ' B ', ' C ',);
, there is
no list in any of them.
Context rules cannot be faulted, and the list is always returned in a scalar context to the number of elements in the list, but in all the statements we wrote earlier, no list has ever appeared.
4. How to use a list in a scalar context
If you want to do this, the method is to explicitly tell the Perl assignment number to the right of a list instead of a comma-expression:
$scalar = @{[' A ', ' B ', ' C ',]};
the square bracket to the right of the assignment tells Perl that this is a reference to an anonymous list, and @{$aref} is the dereference of the list, so the assignment number to the right we get a list "(' A ', ' B ', ' C ')" instead of the comma expression "(' a ', ' B ', ' C ')". In terms of context rules, the list gets the number of list elements in the scalar context. Of course $scalar is assigned a value of 3.
Looking back, let's look at another statement:
@array = qw/a b c/;
according to the QW expansion rule, this statement is equivalent to the following statement:
@array = (' A ', ' B ', ' C ',);
The assignment number to the left is a list, so this statement is a list context, and Perl will interpret the right of the assignment number in the list context as a list "(' A ', ' B ', ' C ', ') ' instead of a comma expression" (' a ', ' B ', ' C ', ') ". This is not difficult to understand--in the context of the list of course Perl would expect a list, and in the scalar context of course Perl would expect a scalar. So the same expression
(' A ', ' B ', ' C ',)
is treated as a comma expression in a scalar context and is considered a list in the context of a list. Perl is just looking for what it expects to get.
5. To understand Perl rather than let Perl understand you
It was a very puzzling thing when I learned Perl 2 years ago and understood why my code worked like this when I consulted a lot of information. I think it's also a transition that a Perl programmer has to undergo:
Perl is a little different from other languages-it needs Perl thinking when it comes to Perl, and you need to understand Perl rather than letting Perl understand your code.
How to get the list in Perl scalar context