in reply to Tricky scope problem

And you've made debugging tricky by not providing code that clearly replicates your issue - neither Foo nor Bar are ever called or referenced, your global $gVar is never assigned a value and the flow of your program is unclear. Please read I know what I mean. Why don't you?.

Based on your comments, it looks like you expect to assign $gVar a value as a loop index and then maintain that value when Bar is called within the loop. However, when you use $gVar as the index on your foreach, you actually create a lexically scoped copy (or rather a local alias for the list element). When you then call Bar, it only sees the global. It's discussed (briefly) in Foreach Loops. Perhaps this example will provide clear flow:

my $var = 5; foreach $var (1 .. 3) { print $var; print_var(); } print $var; sub print_var {print $var};

Outputs: 1525355

Update: Cleaned up some unclear language.

Replies are listed 'Best First'.
Re^2: Tricky scope problem
by lostjimmy (Chaplain) on Apr 11, 2009 at 00:07 UTC

    Wow! Learn something new every day. I'm glad I've never run into this. It would have driven me nuts.

    So with that being said, do you have any idea why this is implemented in such a way? Why does it become "implicitly local to the loop", hiding the global var's value? This is completely unexpected (at least to me), and doesn't really seem like the logical thing.

      Why does it become "implicitly local to the loop", hiding the global var's value?
      Consider the following code:
      >perl -wMstrict -le "my $scalar = 42; print qq{scalar before subroutine: $scalar}; S(); print qq{scalar after subroutine: $scalar}; sub S { for $scalar (1 .. 3) { print qq{scalar in subroutine for-loop: $scalar}; } } " scalar before subroutine: 42 scalar in subroutine for-loop: 1 scalar in subroutine for-loop: 2 scalar in subroutine for-loop: 3 scalar after subroutine: 42
      In the  for loop in the subroutine, a temporary list is generated and  $scalar is aliased to each element of the list in turn. Then the subroutine exits. What happens to the temporary list upon exit from the subroutine (or probably upon exit from the loop, actually)? To what element of the list should  $scalar remain aliased after exit from the subroutine (or the loop)? The answer to this question seems to be 'None', since the list no longer exists. Hence, implicit loop locality.
        Ah I see. That makes total sense. Thanks for the enlightenment!
      It's done this way to allow for the following magic:

      > perl -e '@arr = (1,2,3);$_++ foreach @arr;print @arr,"\n"' 234

      By aliasing the loop variable, we gain the power to use foreach (and grep and map...) to create simple list operations without dealing with index syntax.

        Thanks, kennethk. I understand very well the aliasing provided by the loop variable. I just hadn't understood why it became implicitly localized to the loop. AnomalousMonk explained it perfectly, though.