Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Forcing a list context in Perl

Tags:

perl

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?

like image 890
wwas Avatar asked Jun 16 '13 18:06

wwas


People also ask

What is list context in Perl?

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.

How to convert array to scalar in Perl?

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.

What does scalar function do in Perl?

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.

What is Perl variable context?

Perl treats the same variable differently based on Context, i.e., the situation where a variable is being used.


2 Answers

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.

like image 61
ikegami Avatar answered Oct 03 '22 00:10

ikegami


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.

like image 25
choroba Avatar answered Oct 03 '22 02:10

choroba