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