DEV Community

🌌 Sébastien Feugère ☔
🌌 Sébastien Feugère ☔

Posted on • Updated on

while loops that have an index

Perl5 got this syntax that allow to use a while loop without having to explicitly incrementing an index by doing an i++. It is made possible by the each function.

Let's demonstrate this in a simple test that check that and array and an array ref contains the same things:

# t/01_foo_order.t    
use v5.18;
use Test::More tests => 3; 

my $events_arr_ref = get_events();
my @expected_events = ('foo', 'bar', 'baz');

while ( my ( $i, $event ) = each( @$events_arr_ref )) {
  is @$events_arr_ref[$i], 
    $expected_events[$i], 
    "Array element [ $i is $expected_events[$i]";
}

done_testing();

sub get_events {
  return [ 'foo', 'bar', 'baz' ];
}

Enter fullscreen mode Exit fullscreen mode

Let's execute our test:

prove -v t/01_foo_order.t
1..3
ok 1 - Array element [ 0 ] value is foo
ok 2 - Array element [ 1 ] value is bar
ok 3 - Array element [ 2 ] value is baz
ok
All tests successful.
Files=1, Tests=3,  0 wallclock secs ( 0.03 usr  0.00 sys +  0.07 cusr  0.00 csys =  0.10 CPU)
Result: PASS
Enter fullscreen mode Exit fullscreen mode

while ( my ( $i, $event ) = each( @$events_arr_ref )) {} makes possible to iterate on the $events_arr_ref array reference and for each element found, initializing $i and $event with the right value.

This is quite the same than a for loop except that you don't have to increment the index and that it must be used in case you want to iterate on the whole array.

I use it quite often, can be handsome if you want to avoid $_. Just yet another TIMTOWTDI...

Sources:

Discussion (1)

Collapse
smonff profile image
🌌 Sébastien Feugère ☔ Author

I edited the post with test passing, not failing because why would you do such a thing?