Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,
$a=10; { $a=11; print $a; }

How to refer outside declare variable.

I want to print value of $a is 10

Replies are listed 'Best First'.
Re: How to access outside variable
by ELISHEVA (Prior) on Jan 21, 2011 at 05:37 UTC

    You can't.

    To access both variables the inner and outside variables must be in different packages. In fact, all you are doing in the code above is overwriting the old value (10) with a new value (11).

    To be able to access two variables with the same name at the same time, you would have to do something like this:

    package Frick; # this variable will have the full name $Frick::a; #our makes the variable sharable between packages our $a=10; { package Frack; # This variable will have the full name $Frack::b; # my limits $Frack::b to the package Frack. # No other package will be able to see or use its value my $a=11; print "Frick says $Frick::a, Frack says $a, $Frack::a\n"; #prints: frick says: 10, frack says: 11, 11; }
      Sorry,

      The variable declared as my.

      Rewriting the code

      my $a=10; { my $a=11; print $a; }

      Please consider the file is not an module. It is just simple .pl file.

      I want print value of $a is 10 inside the block which is declared on outside.

        You still can't access the outer value without putting the variables in separate packages and declaring the outer one with our. The second inner my declaration "hides" the first outer my declaration. If you want to access two variables with the same name, you have to give them separate packages, even if it all happens in a single .pl file.

        Packages aren't necessarily modules. You can have many package declarations in a single file and many files sharing the same package declaration. Packages are just namespaces you can use to group together variables and scope them logically rather than via text position (inside/outside curly braces).

        If you really, really don't want to use packages to scope your variables, then you will have to give your inner and outer variables different names. Is there a particular reason you aren't doing that already?

        In case the inner scope isn't just a plain block, but a subroutine, you can use PadWalker to get at the outer scope(s):

        use PadWalker qw(peek_my); my $a=10; sub { my $a=11; my $my = peek_my(1); # one level up print ${$my->{'$a'}}; # 10 print $a; # 11 }->();

        This isn't meant for everyday consumption, though... — better use unambiguous variable names.

        Do it before you override it
Re: How to access outside variable
by lyklev (Pilgrim) on Jan 21, 2011 at 12:11 UTC

    The solution to your problem is by making the outer scoped variable a package variable using our, and referring to it using the implicit main package. The nested variable is a local variable using my. The full routine then becomes

    #!/usr/bin/perl use strict; use warnings; our $a = 10; { my $a = 11; print $a, "\n"; # prints the local variable print $main::a, "\n"; # prints the package variable }

    That said, it is also a trick question during your interview, as you mentioned. Choosing $a or $b for a local variable is always bad, because they are used by sort which means they are somewhat special and can cause strange behaviour.

Re: How to access outside variable
by biohisham (Priest) on Jan 21, 2011 at 10:45 UTC
    Since $a is defined in the same package - main - what happens is that the value of $a gets merely overwritten, variables in the same package are global to that package scope,
    #!/usr/local/bin/perl print __PACKAGE__ ; print "\n"; $a=10; { $a=11; print $a,"\n"; print __PACKAGE__ ; }
    look up __PACKAGE__ in perlmod and perldata, coping with scoping can be a good read as well..


    Excellence is an Endeavor of Persistence. A Year-Old Monk :D .