http://qs321.pair.com?node_id=11120536

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

$count = 0; while ($count < 10) { $count += 1; print "count is now $count\n"; }

I don't get it. Why is it printing till 10 if the conditional expression asserts it should be less than (<) 10 and not less than or equal (<=) to 10? Shouldn't it print just till 9?

Replies are listed 'Best First'.
Re: Not understanding while loop counting (updated!)
by haukex (Archbishop) on Aug 10, 2020 at 08:14 UTC

    The condition is evaluated before the loop body is executed, and more importantly, you're printing the value immediately after incrementing it, so the condition has no way of being checked after the increment from 9 to 10. Perhaps you need to change the order of the statements, and/or maybe you're thinking of do { ... } while ... (perlsyn)?

    Update: Here's another way to think about it. Every loop can be reduced to a while (true) {...} with a conditional break out of the loop at the appropriate point (and if you want to go even further, you can try unrolling that loop in your head, i.e. think about the order of the operations if there was no loop and the statements were simply repeated Update 2: as davido showed).

    my $count = 0; print "entering loop with count=$count\n"; while (1) { print "before testing, count=$count\n"; last unless $count < 10; print "before incrementing, count=$count\n"; $count += 1; print "count is now $count\n"; } print "exited loop with count=$count\n";

    Update 3: I've now modified the code example to insert lots of debugging prints (see also the Basic debugging checklist) and to fix a logic bug (I had forgotten to invert the condition).

Re: Not understanding while loop counting
by LanX (Saint) on Aug 10, 2020 at 08:15 UTC
    for the same reason why 0 is never printed.

    you print after incrementing but before the next loop iteration is tested.

    just move the print to the top to see the difference.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

Re: Not understanding while loop counting
by davido (Cardinal) on Aug 10, 2020 at 14:59 UTC

    Consider the steps

    • Set count to zero.
    • Check if count is less than ten. It is zero.
    • Increment count to one.
    • print count (1)
    • Do this a few more times........then...
    • Check if count is less than ten. It is nine.
    • Increment count to ten.
    • Print count (10)
    • Check if count is less than ten (it is 10, so it is not less)
    • Do not enter loop body; we're done.

    See: Off by one error


    Dave

Re: Not understanding while loop counting
by pDaleC (Sexton) on Aug 10, 2020 at 14:57 UTC
    You probably want
    $count = 0; while (++$count < 10) { print "count is now $count\n"; }
    But I would suggest using the exact loop style for this situation:
    For ($count=1; $count<10; ++$count) { print "count is now $count\n"; }
      I would suggest using the exact loop style for this situation

      Or the perlish for my $count (1..9) { ... } (personally I reserve for (;;) for more complex cases like modifying the loop variable in the loop body, but TIMTOWTDI).

      Addendum: see also perlsyn#For-Loops

      Perl's C-style for loop works like the corresponding while loop; that means that this:
      for ($i = 1; $i < 10; $i++) { ... }
      is the same as this:
      $i = 1; while ($i < 10) { ... } continue { $i++; }

      NB I have to admit I practically never use continue ...

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

Re: Not understanding while loop counting
by zapdos (Sexton) on Aug 10, 2020 at 22:55 UTC
    Thank you all very much, Wise Monks. ;-)