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

$j=23; LABEL: for ($i=$j; $i<=$#array; $i++) { if ($array[$i] eq "blah") { last LABEL; } elsif ($i == $#array) { $i = 0; next LABEL; } else { next LABEL; } }
My question is.. if I set $i to 0, will the next LABEL take the value of $i that i gave it, or will it go to the next $i in the loop.. so if $i equaled 9 when the loop begain, and it went through that statement, when the next LABEL; command came up, would $i equal 0 when it did the loop again, or would it equal 10?

Replies are listed 'Best First'.
Re: Can I do this?
by chromatic (Archbishop) on Jul 14, 2001 at 07:25 UTC
    The next operator stops the current iteration of the loop and begins the next one. It does not assign $i to $j again. Modifying the loop control variable ($i = 0) and saying next creates an infinite loop. You can verify this by adding the following line as the first line of the loop:

    print "I: $i\n";

    Generally, loops like this are discouraged in Perl because there are better ways to do things. I might write your code like this:

    my $pos = 0; for ($j .. $#array) { if ($array[$_] eq 'blah') { $pos = $_; last; } }
    By the end of my snippet, $pos will either contain the appropriate index, or will still be 0. It's shorter and needs no labels. Best of all, it doesn't need $i, so the question is moot.

    I hope this helps.

    Update: HyperZonk suggests that the original poster may want to search the first half of the array if $j through the end didn't have the element. In that case, maybe the C-style loop is better:

    my ($i, $end) = ($j, $#array); my $pos = 0; for (; $i <= $end; $i++) { last if ($array[$i] eq 'blah'); if ($i == $#array) { $i = 0; $end = $j - 1; } }
    Untested, but it's one way to do it.
Re: Can I do this?
by HyperZonk (Friar) on Jul 14, 2001 at 06:09 UTC
    That should work, but consider:

    $j = 23; $i = $j; LOOP: while (1) { if ($index[$i] eq 'blah') { last LOOP; } elsif ($i == $#array) { $i = 0; } else { $i++; } )


    Update: added missing closing quote.

    Second update: per wog noted that you actually "start over" at 1, because next performs the $i++. However, I think you want to start at the beginning of the array, right? If not, change the code to:

    $j = 23; $i = $j; LOOP: while (1) { if ($index[$i] eq 'blah') { last LOOP; } elsif ($i == $#array) { $i = 0; } $i++; )
Re: Can I do this?
by synapse0 (Pilgrim) on Jul 14, 2001 at 06:13 UTC
    My guess would be that another loop would start and $i would initialize to $j again.. But i haven't played with BLOCK: type structs before. Really, instead of asking, you should throw some prints in there and test it out, then ask question if the results puzzle you.. no amount of ppl telling you what will happen will take the place of the experience of experimentation...
    $j=23; $x = 0; LABEL: for ($i=$j; $i<=$#array; $i++) { print "top of loop: \$i = $i\n"; print "interation $x\n"; $x++; if ($array[$i] eq "blah") { print "\$i is blah\n"; last LABEL; } elsif ($i == $#array) { print "\$i == $#array\n"; $i = 0; next LABEL; } else { next LABEL; } }
    -Syn0