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


in reply to Re^2: Variable initialization / reinitialization
in thread Variable initialization / reinitialization

The thing is that you cannot have locally scoped subroutines. All named subroutines are implicitly package level things.

Now, you can declare a named subroutine inside another subroutine. That inner subroutine comes into existence without having to execute the outer subroutine. But, because all named subroutines are all at package level, the inner subroutine can be called from outside the outer one.

So, if the inner subroutine refers to lexical variables belonging to the outer subroutine, Perl has a problem. Those variables notionally don't exist until the outer subroutine is entered. It's a mess, which Perl resolves by inventing new versions of the variables apparently shared by the inner and outer subroutines. Those new versions are effectively outside the inner subroutine -- so behave, as you observed, much like 'C' statics.

So:

sub outer { my $foo ; .... sub inner { $foo++ ; } ; } ;
is effectively the same as:
sub outer { my $foo ; .... } ; { my $foo ; sub inner { $foo++ ; } ; } ;

(You can declare named subroutines in other blocks, such as inside an eval, which is probably why you can do so in a subroutine. But that's pure speculation.)

Replies are listed 'Best First'.
Re^4: Variable initialization / reinitialization
by BTrey (Novice) on Feb 09, 2009 at 14:14 UTC
    Thanks for the lucid explanation of why the problem occurred. I wasn't aware that you could not have locally scoped subroutines. As is probably obvious from my code, I came to Perl by way of C and am still learning the nuances of the language.