Why doesn't cut an item from a list return a list?
When working with lists in a scalar context, the last element is returned:
@l = qw/ a b c d /;
print scalar ( 1, @l ); # prints 4
The last element of the list @l
, its length in scalar context is 4
So, the last element @l
.
Why, when I do a slice, I don't get this item?
print (( 1, @l )[1]); # prints 'a'. expect: abcd
PS. Maybe I should ask: why is there no flattening in the first example?
source to share
This is due to the difference in behavior between list and scalar context and the fact that it scalar
is an operator and not a subroutine call. scalar
can only take one operand, so if you pass multiple parameters, they are placed in a scalar context. This is not like normal subroutine calls, where parameters are always in the context of a list.
In scalar context, the comma operator evaluates and discards its left operand, and then evaluates its right operand. So scalar(1, @l)
evaluates and discards 1
and then evaluates @l
. As you say it is 4 because it @l
has four elements
The list locus, unsurprisingly, overlaps the list context, and in the list context, commas separate the list items, and arrays and hashes are aligned. So, is the (1, @l)[1]
same as (1, qw/ a b c d /)[1]
which isa
Perl array operators like push
and pop
behave in a similar way. push @l, 1
won't be very helpful if it behaves just like a normal subroutine and expands topush 'a', 'b', 'c', 'd', 1
source to share
In the first example, you are forcing the scalar context with scalar
.
In scalar content, ,
interpreted as a scalar binary operator that returns the right argument.
@l = qw/ a b c d /;
@m = (1, @l); # (1,@l) is interpreted in list context
print scalar(@l); # prints 4
print scalar(@m); # prints 5
print scalar('a',@l); # ('a',@l) is interpreted in scalar context
# prints scalar(@l)
print scalar(@l,'a'); # (@l,'a') is interpreted in scalar context
# prints a
perldoc -f scalar
scalar EXPR EXPR
forces are interpreted in scalar context and return EXPR.
man perlop
Comma Operator
Binary "," is the comma operator. In a scalar context, it evaluates the left argument, discards that value, then evaluates its right argument, and returns that value. It looks like a C comma.
In the context of a list, it is simply the list argument separator and inserts both of its arguments into the list. These arguments are also evaluated from left to right.
source to share