Perl DISCUSSION

Why does a Perl array give its element count in one statement and its first element in another?

Started by anish Perl scalar contextlist contextarray lengthscalar functioncontext bugs
5 replies 248 views 6 participants
Latest activity · 30 Sep 2026

Why does a Perl array give its element count in one statement and its first element in another?

anish Perl Forum
#1

I am confused by how Perl treats arrays. With my @pins = (2, 3, 5, 7); the line my $n = @pins; gives 4, but my ($n) = @pins; gives 2. print "Pins: @pins\n"; prints the values, while print "Pins: " . @pins . "\n"; prints 4.

What rule decides whether I get the length or the elements, and what is the safe way to get the number of elements every time?

Community replies 5

Re: Why does a Perl array give its element count in one statement and its first element in another?

#2

Every Perl expression is evaluated in either scalar or list context, decided by what surrounds it. An array in list context yields its elements; in scalar context it yields its element count. Assignment to a plain scalar, my $n = @pins;, is scalar context, so you get 4. Parentheses on the left, my ($n) = @pins;, make it a list assignment: the elements are copied position by position, $n receives the first one (2) and the rest are dropped.

Re: Why does a Perl array give its element count in one statement and its first element in another?

#3

Your two print lines follow the same rule. Inside double quotes an array is interpolated as its elements joined with a space (the value of $"). The concatenation operator . needs a single string on each side, so it puts @pins in scalar context and you get the count. Note that print "Pins: ", @pins; with a comma is different again: the arguments of print are a list, so the elements are printed with nothing between them, giving Pins: 2357.

Re: Why does a Perl array give its element count in one statement and its first element in another?

#4

To state the intent explicitly, use scalar(@pins); it forces scalar context anywhere, for example print "Count: ", scalar(@pins), "\n";. Numeric comparisons already supply scalar context, so if (@pins > 3) and while (@queue) are fine as they are.

$#pins is the index of the last element, not the count: here it is 3, and it is -1 for an empty array. Loops written as for my $i (0 .. $#pins) rely on that.

Re: Why does a Perl array give its element count in one statement and its first element in another?

#5

Context also changes what functions return, which is where real bugs come from. my $t = localtime; gives a readable date string, while my @t = localtime; gives nine numbers (seconds, minutes, hours, day and so on). A subroutine that ends with return @results; returns the count to a caller that writes my $r = get_results();. Inside a sub you can check which context you were called in with wantarray.

A list literal is not an array: my $x = (4, 5, 6); sets $x to 6, because in scalar context the comma operator evaluates each item and keeps the last. With use warnings Perl flags that line.

Re: Why does a Perl array give its element count in one statement and its first element in another?

#6

Two idioms build on this. my $count = () = $text =~ /\d+/g; counts regex matches: the empty list forces the match into list context, and a list assignment evaluated in scalar context yields the number of items on its right side. And for hashes, use scalar(keys %h) for the number of keys; it behaves the same on every Perl version, whereas a bare hash in scalar context returned a bucket-usage string such as 3/8 on older releases.

TEP COMMUNITY