SPUG: Predeclaring packages

DeRykus, Charles E charles.e.derykus at boeing.com
Sat Jan 3 02:50:09 PST 2009


 
> ...

> > 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" }

>> } 


Thanks for the explanation but your INIT block also exposes a value
for $greeting within the scope of the INIT block, correct...? whereas, 
without ensuring that $greeting gets set in that particular scope, if 
you had said this for instance:


   use strict;
   use warnings;
   

   Hello::sayHi();
   exit(0);

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

This'll enerate expected errors  ====>  
    Variable "$greeting" is not imported ...
    Global symbol "$greeting" requires explicit package name ...

?

-- 
Charles DeRykus


More information about the spug-list mailing list