SPUG: Predeclaring packages
Ronald J Kimball
rjk-spug at tamias.net
Fri Jan 2 20:42:04 PST 2009
On Fri, Jan 02, 2009 at 08:11:22PM -0800, DeRykus, Charles E wrote:
>
> > I did some more experimentation, and I think I know what was confusing me.
> > Maybe you can confirm this: the scoping for an 'our' statement occurs during
> > compiling, but actual variable assignments occur during runtime.
Yes, that is basically correct.
> > use strict;
> > use warnings;
>
> > Hello::sayHi();
> > exit(0);
>
> > package Hello;
> > {
>
> > our $greeting = 'Hello there';
>
> > sub sayHi { print $greeting . "\n" }
>
> > }
>
>
> Um, it's not a compilation vs. runtime issue: "our" just exposes a value
> for a global variable within a specific scope. Since the <our $greeting =
> 'Hello there'> in package Hello is not in scope when Hello::sayHi() is
> called, it's undefined. That's why it only works if you declare
> <$Hello::greeting = 'Hello there'> before the call to Hello::sayHi. Note
> though a deckaration such as <"our $greeting = "Hello there'> just prior
> to Hello::sayHI wouldn't work because the scope of 'our' won't extend
> into package Hello. And that's why I suggested assigning the global
> variable to an "our" variable to avoid tediously needing a package
> qualifier for $greeting when used in other scopes.
In fact, it /is/ a compilation vs. runtime issue. The <our $greeting =
'Hello there'> in package Hello is in the same scope as the sayHi
subroutine. If it were a scoping issue, then there would have been an
error: Global symbol "$greeting" requires explicit package name.
The reason the code results in an uninitialized value warning is that the
assignment has not been executed yet when Hello:sayHi() is called.
One simple way to resolve this - and to demonstrate that is a compilation
vs. runtime issue - is to use a BEGIN or INIT block to ensure
that the assignment is executed before runtime. (BEGIN blocks are
executed immediately during compilation; INIT blocks are executed between
compilation and runtime.)
use strict;
use warnings;
Hello::sayHi();
exit(0);
package Hello;
INIT {
our $greeting = 'Hello there';
sub sayHi { print $greeting . "\n" }
}
Ronald
More information about the spug-list
mailing list