[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