I'm trying to understand Perl context and I tripped over a rock;
Given the code;
#!/usr/bin/perl my $b = (33,22,11); print "$b\n"; my $b = () = (33,22,11); print "$b\n"; my @b = (33,22,11); print "@b\n"; my @b = () = (33,22,11); print "@b\n";
The results are (the last line is blank);
11 3 33 22 11 <>
Since the 2nd print returned the length of the list I was assuming that somewhere an array was generated since an array in a scalar context evaluates to its length. But the 4th print seems to belie that assumption. I was expecting to see '33 22 11'
printed but got nothing instead. What's happening here?
In a list context, Perl gives the list of elements. But in a scalar context, it returns the number of elements in the array. Perl presumes List values in “List Context”, where as the list could have any number of elements or it can have only one element or it can even be desolated.
In order to provoke Scalar Context using an array, it is required to assign an array to a Scalar variable. When the condition section of the if-statement presumes a single value then that is Scalar Context. In the below program, if-statement contains array, in scalar context, array returns the number of elements in it.
scalar keyword in Perl is used to convert the expression to scalar context. This is a forceful evaluation of expression to scalar context even if it works well in list context.
Perl treats the same variable differently based on Context, i.e., the situation where a variable is being used.
You're confused because you think =
is a single operator while it can result in two different operators: a list assignment operator or a scalar assignment operator. Mini-Tutorial: Scalar vs List Assignment Operator explains the differences.
my $b = (33,22,11); ------------------ Scalar assign in void context. ---------- List literal in scalar context. Returns last. my @b = (33,22,11); ------------------ List assign in void context. ---------- List literal in list context. Returns all. my $b = ( () = (33,22,11) ); --------------------------- Scalar assign in void context. ------------------- List assign in scalar context. Returns count of RHS ---------- List literal in list context. Returns all. my @b = ( () = (33,22,11) ); --------------------------- List assign in void context. ------------------- List assign in list context. Returns LHS. ---------- List literal in list context. Returns all.
As for your title, forcing list context is impossible per say. If a function returns a list when a scalar is expected, it results in extra values on the stack, which leads to operators getting the wrong arguments.
You can, however, do something like:
( EXPR )[0]
or
( EXPR )[-1]
EXPR
will be called in list context, but the whole will return just one element of the returned list.
List assignment in scalar context returns the number of elements on the right hand side (case 2). The case 4 first assigns (33, 22, 11)
to ()
, and then assigns ()
(whose value has not changed) to @b
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With