Skip to content

each @array in Perl 5.12

June 6, 2010

Don’t recall seeing anyone blog about it and in fact the documentation is pretty sparse but from Perl 5.12 each can now iterate over an array like so:

use 5.012;
use warnings;

my @array = 'a' .. 'h';

while (my ($i, $val) = each @array) {
    say "$i => $val";

each on an array returns two values… the index and the value of the current iteration. Thus we get this output from above code:

  0 => a
  1 => b
  2 => c
  3 => d
  4 => e
  5 => f
  6 => g
  7 => h

Anyway to save me thinking up a blog post please excuse me while I just regurgitate my Stackoverflow answer I gave earlier today about using each with an array:

Starting with Perl 5.12, each is now more flexible by also working on arrays:

use 5.012;
use warnings;

my @tokens = 'a' .. 'z';

while (my ($i, $val) = each @tokens) {
    if ($val =~ m/[aeiou]/) {
        ($i, $val) = each @tokens;   # get next token after a vowel
        print $val;

# => bfjpv

One caveat with each, remember the iterator is global and is not reset if you break out of a loop.

For eg:

while (my ($i, $val) = each @tokens) {
    print $val;
    last if $i == 12;

# => abcdefghijklm

my ($i, $val) = each @tokens;
say "Now at => $val ($i)";         # Now at => n (13)

So use keys or values to manually reset the iterator:

keys @tokens;                      # resets iterator
($i, $val) = each @tokens;
say "Now at => $val ($i)";         # Now at => a (0)


I’ve just come back from a nice weeks break… so I’m still a lazy git in holiday mode here :)


7 Comments leave one →
  1. poisonbit permalink
    June 6, 2010 6:24 pm

    Is there any reason to take a loop iterator out of the loop by default ?

    I don’t understand very well this change, I think that makes more sense to “add code” those who want a loop iterator outside the loop, better than to make “add code” for those who reuse semantically the same iterator in loops.

    • June 7, 2010 11:27 am

      Hi poisonbit,

      If you referring to my last two bits of code then I’m only using this as an example for the “caveat”.


  2. Paul Evans permalink
    June 7, 2010 10:58 am


    So now 5.12 has further extended the awkward action-at-a-distance misfit of ‘each’ to operate on more containers than it used to on 5.10. I can see this being abused far more often, creating lots more bugs where the globalness of it accidentally leaks out, than I can see cases for it being useful.

    foreach my $idx ( 0 .. $#arr ) { my $elem = $arr[$idx] } is already neat enough. If you actually wanted to preserve the index from one loop to the next; just remove that ‘my’ start using a C-style for() loop.

    each is useful on hashes because you can’t just do that with $key; there is no obvious $key++ operation to walk to the “next” key.

    • June 7, 2010 11:41 am

      Hi Paul,

      Actually I think its quite a useful addition and I much prefer its succinctness over the alternatives. However its good to be wary and I for one would do my best avoid any self abuse it may cause using it :)

      BTW… using an iterator is my preferred solution. For eg. Array::Iterator mentioned in another answer in that stackoverflow question is something I would recommend.

      chars Barry

  3. Ether permalink
    July 12, 2010 4:39 pm

    keys() on an array? Really? How interesting.


  1. each to their own (autobox) « transfixed but not dead!

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

%d bloggers like this: