in reply to Deparse broken or just misunderstood?

The problem seems vaguely related to another for loop behaviour that I think is unintuative and could be construed as a bug.

Sometimes you need to know what value a loop counter had when the loop exited early. If you use my on the loop counter, then it has gone out of scope when the loop exits and this information is lost.

The apparently obvious thing to do is to declare the loop counter before the loop so that it still exists afterwards, but this doesn't work:

#! perl -slw use strict; my $i = 123; for $i ( 0 .. 10 ) { last if $i == 5; } print $i; __END__ 123

Even though the strict is enabled, no warning is issued, which means the $i used by the for loop can only be the lexical declared above it. But still the value of $i after the loop is the value set preceding it. The only way to view this is that $i has been localised for the duration of the loop; but you (the programmer) cannot use local on a lexical.

It is probably a side-effect of making $i an alias for to the values it takes on for the duration of the loop, but it is unintuative and darned annoying.


Examine what is said, not who speaks.
"Efficiency is intelligent laziness." -David Dunham
"Think for yourself!" - Abigail        "Time is a poor substitute for thought"--theorbtwo
"Memory, processor, disk in that order on the hardware side. Algorithm, algorithm, algorithm on the code side." - tachyon

Replies are listed 'Best First'.
Re^2: Deparse broken or just misunderstood?
by Roy Johnson (Monsignor) on Nov 15, 2004 at 17:25 UTC
    That behavior is, at least, fully documented. for loop variables are always localized (or lexically declared) to the block. Predicate-for cannot have a named loop variable. (Note: my situation did not concern itself with loop variables, but lexicals declared in the list of a block-for are scoped to the block, while those in a predicate-for are scoped to the enclosing block/file)

    It might be nice to expand the syntax to allow a reference to a scalar variable to be given as the loop variable, and the referenced variable would be used instead of a newly-created variable.

    my $i = 123; for \$i ( 0 .. 10 ) { last if $i == 5; } print $i; __END__ 5
    The present situation provides a use for a C-style for loop:
    my $i = 123; for ($i = 0; $i <= 10; ++$i) { last if $i == 5; } print $i; __END__ 5

    Caution: Contents may have been coded under pressure.