Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

behavior of new 'each @array' in scalar context

Perl 5.14 gives us the extended each function which operates on arrays as well as hashes:

When called in list context, returns a 2-element list consisting of the key and value for the next element of a hash, or the index and value for the next element of an array, so that you can iterate over it. When called in scalar context, returns only the key (not the value) in a hash, or the index in an array.

An example using list context works:

perl -E 'say $^V'

v5.14.0

perl -E '@a = (1..10); while (my ($i, $elem) = each @a) {say "\$a[$i] = $elem"}'

$a[0] = 1
$a[1] = 2
$a[2] = 3
$a[3] = 4
$a[4] = 5
$a[5] = 6
$a[6] = 7
$a[7] = 8
$a[8] = 9
$a[9] = 10

however in scalar context, I get nothing:

perl -E '@a = (1..10); while (my $i = each @a) {say $i}'

Can anyone offer any insight? I have a feeling that this will be a head slapper when someone points out my error, but perhaps not.

Edit: In fact the while loop has nothing to do with it:

perl -E '@a = (1..10); $i = each @array; say $i'

gives no output either. s'@array'@a' oops.

Edit 2:

As per daxim's comment:

perl -MDevel::Peek -E'@a = (1..10); Dump each @a'

SV = IV(0x161ce58) at 0x161ce68
  REFCNT = 1
  FLAGS = (TEMP,IOK,pIOK)
  IV = 0

however I have no idea what that tells me.

Edit 3:

It seems that the loop exits because the first index is 0, or false. I have filed a bug ( http://rt.perl.org/rt3/Ticket/Display.html?id=90888 ) since this doesn't seem to be the desired behavior.

like image 606
Joel Berger Avatar asked May 17 '11 16:05

Joel Berger


2 Answers

You need to do while (defined( my $i = each @array )) { say $i } otherwise it'll stop at the first index (0) since it is false.

like image 154
phaylon Avatar answered Nov 16 '22 03:11

phaylon


[ The contents of this post are wrong. There must have been a bug in my test. I'm not deleting it due to the presence of good comments. ]

scalar each %hash works thanks to each hash having an iterator associated with it. I suspect that such an iterator wasn't added to arrays.

This is a bug, as each says:

When called in scalar context, returns only the key (not the value) in a hash, or the index in an array.

Please file a report using perlbug.

like image 36
ikegami Avatar answered Nov 16 '22 02:11

ikegami