[Wellington-pm] A question about scopes

Jacinta Richardson jarich at perltraining.com.au
Sun Mar 26 04:23:20 PST 2006


G'day Cliff,

I don't know how useful you'd find it, but we cover scoping and scopes in our
Introduction and Intermediate Perl course notes, available at
http://perltraining.com.au/notes.html

Scope itself is covered in the Intro Conditionals chapter, with further coverage
when we get to Modules and Packages in the Intermediate course.

Cliff Pratt wrote:
> Say I have a Package and a PERL script.

It's "Perl" typically.  ;)

> If the package uses a variable 
> $foo, and so does the script, I should be able to access the script's 
> version of $foo by $main::foo in the package. Am I correct?

Consider the following case:
---------------------------------------------------
#!/usr/bin/perl -w
use strict;

my $foo = 4;         # $foo in the main package
my $bar = 10;        # $bar in the main package

print "$foo\n";      # prints "4".

if(1) {
     my $foo = 1;    # $foo in the main package, but over-shadows previous

     $foo++;

     print "$foo\n"; # prints "2"
}

print "$foo\n";      # still prints "4"


package bar;

my $foo = 7;         # $foo in the bar package (generates warning if in
                       same file as above code)

print "$foo\n";      # prints "7".

print $main::foo;    # undefined!
print $main::bar;    # undefined!

print "$bar\n";      # prints "10" but only if this is all in the same file
---------------------------------------------------


$main::foo is undefined because $foo was declared with "my".  Declaring a
variable with "my" means that it lasts from that location to the end of the
enclosing block ( }  or end of tile ).  "my" variables are not "package"
variables, but are rather lexical variables.

If we separate the above code into two files we can see this more clearly.

---------------------------------------------------
### main.pl
#!/usr/bin/perl -w
use strict;

require 'bar.pl';    # for example... usually "use bar;"

my $foo = 4;         # $foo in the main package
my $bar = 10;        # $bar in the main package

print "$foo\n";      # prints "4".

if(1) {
     my $foo = 1;    # $foo in the main package, but over-shadows previous
                     # This is *not* the same variable as $foo above.

     $foo++;

     print "$foo\n"; # prints "2"
}

print "$foo\n";      # still prints "4"
---------------------------------------------------
### bar.pl
package bar;

my $foo = 7;         # $foo in the bar package

print "$foo\n";      # prints "7".

print $main::foo;    # undefined!
print $main::bar;    # undefined!

#print "$bar\n";     # no $bar defined in this scope
---------------------------------------------------


In the above example, there is no way that the code in package bar can access
the $bar declared in main.pl.  Likewise, there is no way for the main package to
access the $foo declared in bar.pl.


> If $bar is defined in a sub in the package (eg my $bar), its scope is 
> just the sub, isn't it? 

Yes.

> How do I make the scope "global" to the package 
> so that any sub can find it? (I know "global" is not technically correct 
> here) Define it outside any subs in the package?

Yes.  Although you may not actually need to do this.

> Does code outside a sub 
> in a package ever get executed?

Yes, it gets compiled and executed as soon as Perl sees it either "use"d or
"require"d.  "use bar;" is essentially the same as:

BEGIN {
    require "bar.pl";
    bar::import();
}

so that it goes off before all other code compilation and execution.

> If I make $bar "global" to the package, is there a clever way of 
> avoiding qualifying it all the time to distinguish it from the script's 
> version of $bar?

If you declare $bar in the top level scope, within a package, then you can refer
to it as $bar within that package where-ever you need to refer to it -- Just as
I did with $foo in the two examples.  This is regardless of whether you declared
it as a lexical variable or as a shared (global) variable.

All the best,

     Jacinta

-- 
   ("`-''-/").___..--''"`-._          |  Jacinta Richardson         |
    `6_ 6  )   `-.  (     ).`-.__.`)  |  Perl Training Australia    |
    (_Y_.)'  ._   )  `._ `. ``-..-'   |      +61 3 9354 6001        |
  _..`--'_..-_/  /--'_.' ,'           | contact at perltraining.com.au |
 (il),-''  (li),'  ((!.-'             |   www.perltraining.com.au   |




More information about the Wellington-pm mailing list