Local and Global variables in perl

前端 未结 4 1350
不思量自难忘°
不思量自难忘° 2020-12-03 21:09

I am having few doubts about the local/our scope in Perl. I read a lot of documentation, but I am still in confusion is there. Following are the confusions

4条回答
  •  南方客
    南方客 (楼主)
    2020-12-03 21:37

    Here's what I found out about variable scopes:

    my declarations are pretty clear and straightforward if used inside blocks. If used in main outside any block, they are a bit different though, meaning that a my variable declared outside a block is visible even inside functions called from anywhere inside the same file as long as these functions are defined within the same file. If declared inside a block, though, they are not visible to functions even if called from the same block. All my variables seem to live on the stack. And: you cannot localize them with local.

    our variables live on the heap. Even if you have a my variable by the same name, the our variable can still be accessed through ${'var'}, which looks up a variable of that name in the symbol table and dereferences it. my variables, on the other hand, have not symbol table entries.

    local variables seem to me like a relic from former Perl versions. They are just re-assignments to global (our) variables with block scope and resume their former values after the block terminates. I can see no real sense in using them.

    My little program below shows all this, and it shows how badly a declared() test is missing, beyond the well-known defined() test, to identify undeclared variables as such.

     #!/usr/bin/perl
    
     use strict;
    
     ### This is about variable scoping with my, our and local
     my $fsv = "file scope";                 # visible for all code in this file
     our $gsv = "global scope";              # not different from my $fsv, except in packages
     our $lsv = "global";                    # global scope, but localized in subsequent block
    
     {
        my $bsv = "lex scope";               # visible only inside this block, not even in subs called from here
        $gsv = "visible everywhere";
        local $lsv = "global, but localized val";
    
        print "This is variable \$bsv with value $bsv inside block\n";
        print "This is variable \$fsv with value $fsv inside block\n";
        print "This is variable \$lsv with value $lsv inside block\n\n";
        print_vars("calledfromblock");
     }
    
     print_vars("calledfromoutside");
    
    
     no strict 'vars';                       # needed if testing variable for declaredness rather than definedness
     if ( defined $bsv ) {
        print "\$bsv as defined outside braces: $bsv\n"
     } else {
        print "\$bsv not defined outside braces\n";
     }
     print "This is variable \$lsv with value $lsv outside block\n";
     # use strict 'vars';                    # no strict 'vars' effective even in sub print_vars unless switched back on
    
     sub print_vars
     {
        my $whence = shift;
        my $gsv = "my variable";
        no strict 'refs';                    # needed to access the global var $gsv using ${'gsv'} despite the my declaration
    
        if ( $whence eq "calledfromblock" ) {
           print "\t print_vars called from within the block:\n";
           ( defined $bsv )     ? print "\$bsv is $bsv inside sub\n"     : print "\$bsv not defined inside sub\n";
           ( defined $fsv )     ? print "\$fsv is $fsv inside sub\n"     : print "\$fsv not defined inside sub\n";
           ( defined ${'gsv'} ) ? print "\$gsv is ${'gsv'} inside sub\n" : print "\$gsv not defined inside sub\n";
           ( defined ${'lsv'} ) ? print "\$lsv is ${'lsv'} inside sub\n" : print "\$lsv not defined inside sub\n";
        } else {
           print "\t print_vars called from outside the block:\n";
           ( defined $bsv ) ? print "\$bsv is $bsv inside sub\n" : print "\$bsv not defined inside sub\n";
           ( defined $fsv ) ? print "\$fsv is $fsv inside sub\n" : print "\$fsv not defined inside sub\n";
           ( defined $gsv ) ? print "\$gsv is $gsv inside sub\n" : print "\$gsv not defined inside sub\n";
           ( defined $lsv ) ? print "\$lsv is $lsv inside sub\n" : print "\$lsv not defined inside sub\n";
        }
        print "\n";
     }
    

提交回复
热议问题