Search code examples
perlscopenestedsubroutine

Nested subroutines and Scoping in Perl


I'm writing Perl for quite some time now and always discovering new things, and I just ran into something interesting that I don't have the explanation to it, nor found it over the web.

sub a {
   sub b {
     print "In B\n";
   }
}
b();

how come I can call b() from outside its scope and it works?

I know its a bad practice to do it, and I dont do it, I use closured and such for these cases, but just saw that.


Solution

  • Subroutines are stored in a global namespace at compile time. In your example b(); is short hand for main::b();. To limit visibility of a function to a scope you need to assign an anonymous subroutines to a variable.

    Both named and anonymous subroutines can form closures, but since named subroutines are only compiled once if you nest them they don't behave as many people expect.

    use warnings;
    sub one {
        my $var = shift;
        sub two {
            print "var: $var\n";
        }
    }
    one("test");
    two();
    one("fail");
    two();
    __END__
    output:
    Variable "$var" will not stay shared at -e line 5.
    var: test
    var: test
    

    Nesting named subroutines is allowed in Perl but it's almost certainly a sign that the code is doing someting incorrectly.