Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why slicing element from list do not return list?

Tags:

list

perl

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?

like image 406
Eugen Konkov Avatar asked Jan 21 '26 12:01

Eugen Konkov


2 Answers

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

like image 124
Borodin Avatar answered Jan 24 '26 06:01

Borodin


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.

like image 44
AnFi Avatar answered Jan 24 '26 06:01

AnFi