in reply to loop surprise

In any programming language, "loops are usually special." If you need to capture the value of a loop-control variable beyond the boundaries of the loop, use a separate variable for that purpose. (Remember to initialize it to some value before the loop begins, in case the loop doesn't run at all!) It is very common for various implementation quirks to be used with regard to loops, in the very-important name of efficiency.

Replies are listed 'Best First'.
Re^2: loop surprise
by AnomalousMonk (Archbishop) on Apr 03, 2018 at 18:20 UTC
    It is very common for various implementation quirks to be used with regard to loops, in the very-important name of efficiency.

    Rather than efficiency, I think reliability (or perhaps one should better say coherence) is the key concern. If a topicalized (i.e., localized and aliased) Perl-style loop iterator were left un-de-localized upon exit from the loop, to what would it be aliased? An arbitrary element of some named or referenced array? An item in a temporary list, perhaps a literal (i.e., something unwritable), or the (writeble) return value of a function call? (This point has been touched upon in other replies.) Such a state of affairs seems like a recipe for some very perplexing bugs.

    IOW, if not de-localized, exactly what is the nature of the thing to which  $_ would remain aliased after loop exit in this code:

    c:\@Work\Perl\monks>perl -wMstrict -le "sub F { return 4; } sub G { return 5; } sub H { return 6; } ;; for (F(), G(), H()) { ++$_; printf qq{$_ }; } " 5 6 7
    And why would one want to do that?


    Give a man a fish:  <%-{-{-{-<

      if not de-localized, exactly what is the nature of the thing to which $_ would remain aliased after loop exit

      Aliasing is an implicit reference to the object that is aliased. Like any referenced object, it would remain until all references to it have been removed.

      As for why, to see what was last processed. Sure, you could use an extra variable, but doing so adds more opportunities for introducing bugs.

      Besides, according to Larry, laziness is a virtue.

        But there is already an extra variable conceptually. $current_iterator != $last_iterated, even when they happen to be the same number/item, they are not logically the same concept. I think the possibility of introducing bugs is much larger where the iterator alias is a repurposed package variable instead of block scoped.

      Amusement?