When working with lists in 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 is @l, its length in scalar context is 4
So the last element is @l.
Why when I do slice I do not get this element?
print (( 1, @l )[1]); # prints 'a'. expect: abcd
PS. Maybe I should ask: Why flattening is not happened in first example?
It's because of the difference in behaviour between list and scalar context, and the fact that scalar is an operator and not a subroutine call. scalar can take only a single operand, so if you pass more than one parameter then they are put into scalar context. This is unlike ordinary subroutine calls where the parameters are always in list context.
In scalar context the comma operator evaluates and discards its left-hand operand and then evaluates its right-hand operand. So scalar(1, @l) evaluates and discards 1 and then evaluates @l. As you say, that is 4 because @l has four elements
A list slice, unsurprisingly, imposes list context, and in list context commas separate the elements of a list and arrays and hashes are flattened. So (1, @l)[1] is the same as (1, qw/ a b c d /)[1] which is a
Perl array operators like push and pop behave in a similar way. push @l, 1 wouldn't be much use if it behaved the same way as an ordinary subroutine and expanded to push 'a', 'b', 'c', 'd', 1
In your first example you force scalar context by using scalar .
In scalar content , is interpreted as scalar binary operator returning right side 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
Forces EXPR to be interpreted in scalar context and returns the value of EXPR.
man perlop
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.
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