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;


package Hello;
our $greeting = 'Hello there';
sub sayHi { print $greeting . "\n" }



More information about the spug-list mailing list