pat_mc has asked for the wisdom of the Perl Monks concerning the following question:

Hi, Monks -

I am wondering if there is a special Perl variable (similar to $_, $. and the lot) that contains the number of iterations passed through in any type of Perl loop (be it a for, while or any other type of loop).

I know $. can be interpreted in that way when reading in a file line by line but this only works in a while( <> ) {...} loop.

I would like to know if I always have to construct a separate variable which is incremented on each iteration or if Perl already has this feature built in.

Your comments are much appreciated.

Best regards -

Pat

Replies are listed 'Best First'.
Re: Is there a Perl variable to count iterations in a loop?
by moritz (Cardinal) on Dec 17, 2008 at 21:27 UTC
    There's no such variable built into perl.
Re: Is there a Perl variable to count iterations in a loop?
by ikegami (Patriarch) on Dec 17, 2008 at 21:35 UTC
    No, but if you're iterating over an array, you can do
    for my $i (0..$#array) { print("Element $array[$i] was found at index $i\n"); }
    or (copy element into $e)
    for my $i (0..$#array) { my $e = $array[$i]; print("Element $e was found at index $i\n"); }
    or (alias $e to the element)
    for my $i (0..$#array) { for my $e ($array[$i]) { print("Element $e was found at index $i\n"); } }
Re: Is there a Perl variable to count iterations in a loop?
by toolic (Bishop) on Dec 17, 2008 at 21:53 UTC
    Under limited circumstances, you could use $_ as an iterator, as described in perlvar:
    The default iterator variable in a foreach loop if no other variable is supplied.
    use strict; use warnings; for (1..5) { print 2 * $_, " "; } print "\n"; __END__ 2 4 6 8 10
Re: Is there a Perl variable to count iterations in a loop?
by kyle (Abbot) on Dec 17, 2008 at 21:37 UTC

    You can find a list of special variables—like $.—in perlvar.

Re: Is there a Perl variable to count iterations in a loop?
by roman (Monk) on Dec 18, 2008 at 21:27 UTC

    There is probably no such variable, but you can play with a range operator .. in scalar context:

    my @letters = qw(alfa beta gama); for my $letter (@letters){ warn "iteration is ", scalar($0 .. !$0); }

    The $0, resp. !$0 are just expressions which are allways true, resp. allways false. Unfortunately you cannot use 1, 0 because they are given some special meaning by the range operator.

    Although this "trick" works, it is not particularly self-explainable.

      Wow! That could be really useful. How the heck does it work and is it documented anywhere?

      Update - never mind...

      After some quick research and testing I see that ($0 .. !$0) only increments as it's used. So you can't just pop it into an if statement somewhere to get the current iteration (which would be very useful). You might as well just dedicate a new variable to keep count.

      Interesting none the less.

        Be aware. I just get burned by this hack - the range operator iterates all over its lifetime.

        sub iterate { for my $item ( @_ ){ warn 'iteration '. ($0 .. !$0), "\n"; } } iterate( qw(a b c) ); iterate( 1, 2, 3, 4); iterate( 0 );

        yields

        iteration 1 iteration 2 iteration 3 iteration 4 iteration 5 iteration 6 iteration 7 iteration 8