SPUG: Confusing behaivior with exported variables
Jacinta Richardson
jarich at perltraining.com.au
Tue Mar 24 15:37:29 PDT 2009
Mark Mertel wrote:
> *It does work:*
> **
>
> *package Foo;*
> *my $bar = "foo bar\n";*
> *1;*
> *...*
> **
> *use Foo;*
> *use strict;*
> **
> *print $Foo::bar; # prints 'foo bar'*
> **
> *print $bar; # should throw an error*
>
>
> I'll leave the in-depth explaining of the differences between "lexical
> variables" and "package globals" to other sources, but those are the two
> choices. :)
Technically you're both wrong. Declaring variables with "our" does not make
them global. It makes them package variables. However, as Mark has hopefully
discovered now, declaring variables with *my* does not cause them to behave the
way he thought they did.
Lexical variables (those declared with my) exist for their smallest enclosing
scope. This is either a block (as defined by curly brackets) or the file
they're declared in. Thus:
#!/usr/bin/perl -w
use strict;
my $foo; # Visible to the whole file
while(<>) {
my $bar; # Visible only to the end of the while block
}
Variables declared with my cannot ever be seen outside the file they are
declared in.
Package variables (those declared with our, or created when you mention a
variable without strict turned on) are visible from the point they are created
to the end of their file; and are accessible to other files as well (when
exported or when their full name is used):
# Foo.pm
package Foo;
use strict;
my $foo = "This is lexical";
our $bar = "This is a package variable";
# test.pl
#!/usr/bin/perl -w
use strict;
use Foo;
print "foo: $Foo::foo\n"; # foo: <uninitialised> (looks for package var)
print "bar: $Foo::bar\n"; # bar: This is a package variable
of course, if you stick them both in the *same* file, you can see the lexical
variable:
package Foo;
use strict;
my $foo = "This is lexical";
our $bar = "This is a package variable";
package main;
use strict;
use Foo;
print "foo: $foo\n"; # foo: This is lexical
print "bar: $bar\n"; # bar: This is a package variable
print "foo: $Foo::foo\n"; # foo: <uninitialised>
print "bar: $Foo::bar\n"; # bar: This is a package variable
because the scope of these variables is their smallest enclosing block or file.
Packages do not denote blocks. To get the "correct" effect you'd need more braces:
{
package Foo;
use strict;
my $foo = "This is lexical";
our $bar = "This is a package variable";
}
package main;
use strict;
use Foo;
print "foo: $Foo::foo\n"; # foo: <uninitialised>
print "bar: $Foo::bar\n"; # bar: This is a package variable
Perl's true globals are its special variables, which are visible and changable
by everything - whether you want them to be or not. Package variables are often
called globals, but they're not real globals in the computer science sense.
Close enough though.
J
--
("`-''-/").___..--''"`-._ | 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 spug-list
mailing list