Question

I had assumed that, in perl, $x=(2,3,4,5) and ($x)=(2,3,4,5) would give me the same result, but was surprised at what happened in my tests. I am wondering why this behavior is the way it is and why wantarray behaves differently. Here are my tests and the results:

>perl -e '$x=(1,2,3,5);print("$x\n")'
5
>perl -e '($x)=(1,2,3,5);print("$x\n")'
1
>perl -e '$x=(wantarray ? (1,2,3,5) : 4);print("$x\n")'
4
>perl -e '($x)=(wantarray ? (1,2,3,5) : 4);print("$x\n")'
4

Is this behavior consistent/reliable across all platforms?

Whoops. wantarray is for context of subroutine calls...

>perl -e '$x=test();sub test{return(1,2,3,5)};print("$x\n")'
5
>perl -e '($x)=test();sub test{return(1,2,3,5)};print("$x\n")'
1
>perl -e '$x=test();sub test{return(wantarray ? (1,2,3,5) : 4)};print("$x\n")'
4
>perl -e '($x)=test();sub test{return(wantarray ? (1,2,3,5) : 4)};print("$x\n")'
1

So I guess it is consistent, but why does the list return the last value in scalar context?

Was it helpful?

Solution

So I guess it is consistent, but why does the list return the last value in scalar context?

Because it's useful.

my $x = f() || ( warn('!!!'), 'default' );

Well, more useful than any other alternative, at least. It's also consistent with its stronger cousin, ;.

sub f { x(), y(), z() };

is the same as

sub f { x(); y(); z() };

Each operator determines decides what it returns in both scalar and list context.[1]

There are operators that only even return a single scalar.

say time;             # Returns the number of seconds since epoch
say scalar( time );   # Ditto.

But operators that normally returns more than one scalar and those that return a variable number of scalars cannot possible return that in scalar context, so they will return something else. It's up to each one to decide what that is.

 say scalar( 4,5,6 );           # Last item evaluated in scalar context.
 say scalar( @a );              # Number of elements in @a.
 say scalar( grep f(), g() );   # Number of matching items.
 say scalar( localtime );       # Formatted timestamp.

The list operator (e.g. x,y,z) returns what the last item of the list (z) returns when evaluated in scalar context. For example,

 my $x = (f(),g(),@a);

is a weird way of writing

 f();
 g();
 my $x = @a;

Notes

  1. Same goes for subs, though it's common to write subs that are useless to call in scalar context.

OTHER TIPS

You have two types of assigment.

The first one is in scalar context and that is how the comma operators behave in this context (it evaluates both arguments but discard the one to the left and return the value to the right).

The second one is list context (when you enclose a variable in parentheses you are asking for list context). In list context the comma operator just separates the arguments and returns the whole list.

From the Documentation

Comma Operator

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. In list context, it's just the list argument separator, and inserts both its arguments into the list. These arguments are also evaluated from left to right.

http://perldoc.perl.org/perlop.html#Comma-Operator

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top