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

I have a requirement where i need to increment the FOR loop again even if the condition is already met

for ($i = 0; $i <=100; $i++) { statements ... if (defined $v) && ($i == 100) { $i = 2* $i } }

In the above code, i have defined a value $v and some statements related to $v to be executed only when $i reaches 100. I need to set $i as 200, if $v is defined. My code reaches the condition, however it is not incrementing . Is there a way to make it work

Replies are listed 'Best First'.
Re: Incrementing the loop again.
by Corion (Patriarch) on Mar 12, 2016 at 15:33 UTC

    I don't understand your description of your requirement, but most likely you don't want to use a for loop but instead a while loop:

    my $i = 0; my $limit = 100, while( $i <= $limit ) { $i++; if( $v and $i == $limit ) { $limit = 200; }; };
Re: Incrementing the loop again.
by GrandFather (Saint) on Mar 12, 2016 at 22:03 UTC

    Using a "magic" value like that sounds like a nasty hack to avoid an extra variable. Show us the context where the 2 * $i hack is important and we'll show you a cleaner way to achieve the goal.

    As others have mentioned Perl offers a much cleaner for loop over a list: for my $index (0 .. 100) which makes the loop constraints clearer and less error prone. Adding a flag variable such as $hadEvent means the loop variable is just a loop variable and the intent of the "magic" is obvious, in fact not even magic any more.

    Premature optimization is the root of all job security
Re: Incrementing the loop again.
by 1nickt (Canon) on Mar 12, 2016 at 15:41 UTC

    Are you sure about the value of $v? Have you printed it out and examined it?

    I can't see the point in incrementing a counter variable after the end of the loop, but a more natural way to write your loop in Perl would be:

    my $i = 0; for ( 1 .. 100 ) { $i++; # statements $i = 200 if $i == 100 and defined $v; }

    Hope this helps!


    The way forward always starts with a minimal test.

      Thanks for your replies folks. In the above code, once $i is incremented to 101, it won't hit the condition

      if $i == 100 and defined $v;

      I wanted to execute the statements after the above pasted code, once $i becomes 101 to 200

Re: Incrementing the loop again.
by Laurent_R (Canon) on Mar 12, 2016 at 20:10 UTC
    I do not see the point of modifying $i when you reach the end of the loop (and it is a bit awkward and confusing), but if you do it, it works:
    $ perl -e 'my $v = 1; > for ($i = 0; $i <=100; $i++) { > $i = 2* $i if defined $v and $i == 100; > } > print $i;' 201
    So, I would assume that, probably, $v is not defined in your case.

    Having said that, you probably don't really want to use a C-style for loop for that, but rather a while loop.

Re: Incrementing the loop again.
by Marshall (Canon) on Mar 13, 2016 at 06:24 UTC
    This is rather odd looking code for a number of reasons.

    First it is very odd for the "for loop" variable, in this case, $i to have scope outside of the for loop. Normally these things are coded as:  for (my $i=0; $i <=100; $i++){} #after the "for loop", $i has no scope.

    But as another point, in Perl, C Style "for loops" themselves are rare. Usually better coded as for my $i (0..100){}. These C style for loops are very error prone critters, due to the "off by one" errors that can happen.

    In this case, there is of course no need to check for $i==100 within the loop. That only happens on the last loop iteration. So this is the same thing:

    my $i; for ($i = 0; $i <=100; $i++) { statements ... } $i = 200 if defined ($v); #same thing as your code #$i is 101 here, but it was #100 on last loop iteration #test can be moved outside of the loop
    However there is a big problem with this optional definition of a variable, $v. I don't see how that works? Please show your proposed code for that. I think that you should define $v and then check if 0/1 false or non zero? I am not sure from the requirements exactly what you intend.