In Perl prior to 5.10, you can say
#!/usr/bin/perl
use strict;
use warnings;
my @a = qw/a b c d e/;
my $index;
for my $elem (@a) {
print "At index ", $index++, ", I saw $elem\n";
}
#or
for my $index (0 .. $#a) {
print "At index $index I saw $a[$elem]\n";
}
In Perl 5.10, you use state to declare a variable that never gets reinitialized (unlike ones create with my). This lets you keep the $index
variable in a smaller scope, but can lead to bugs (if you enter the loop a second time it will still have the last value):
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
my @a = qw/a b c d e/;
for my $elem (@a) {
state $index;
say "At index ", $index++, ", I saw $elem";
}
In Perl 5.12 you can say
#!/usr/bin/perl
use 5.012; #this enables strict
use warnings;
my @a = qw/a b c d e/;
while (my ($index, $elem) = each @a) {
say "At index $index I saw $elem";
}
But be warned: you there are restrictions to what you are allowed to do with @a
while iterating over it with each
.
It won't help you now, but in Perl 6 you will be able to say
#!/usr/bin/perl6
my @a = <a b c d e>;
for @a Z 0 .. Inf -> $elem, $index {
say "at index $index, I saw $elem"
}
The Z
operator zips the two lists together (i.e. it takes one element from the first list, then one element from the second, then one element from the first, and so on). The second list is a lazy list that contains every integer from 0 to infinity (at least theoretically). The -> $elem, $index
says that we are taking two values at a time from the result of the zip. The rest should look normal to you (unless you are not familiar with the say
function from 5.10 yet).