Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[BUG] requiring modules and the default package

0 views
Skip to first unread message

Michael Schwern

unread,
Apr 13, 2004, 2:49:25 PM4/13/04
to perl5-...@perl.org
foo.pl:

sub _package { print __PACKAGE__ }
1;


bar.plx:

package Bar;
require './foo.pl';
Bar::_package();


Why does that print 'main'? By my understanding, __PACKAGE__ is the
package that the code was compiled in. If it was compiled in main, why
is _package in Bar's symbol table? Bug or feature?

Now here's where it gets curious:

Load.pm:

package Load;

package Bar;
require './foo.pl';


bar.plx:

package Wiff;

use lib '.';
use Load;

package Wang;
Bar::_package();


foo.pl remains as before. Run that and you get 'Wiff'. Huh?

Martyn J. Pearce

unread,
Apr 15, 2004, 12:36:12 PM4/15/04
to Michael Schwern, perl5-...@perl.org
On Tue, Apr 13, 2004 at 02:49:25PM -0400, Michael Schwern wrote:
> foo.pl:
>
> sub _package { print __PACKAGE__ }
> 1;
>
>
> bar.plx:
>
> package Bar;
> require './foo.pl';
> Bar::_package();
>
>
> Why does that print 'main'? By my understanding, __PACKAGE__ is the
> package that the code was compiled in. If it was compiled in main, why
> is _package in Bar's symbol table? Bug or feature?


I think this is because the effect of 'package' is limited to the current file,
being the current compilation unit.

From perldoc -f package:

package Declares the compilation unit as being in the given
namespace. The scope of the package declaration is
from the declaration itself through the end of the
enclosing block, file, or eval (the same as the "my"
operator).

> Now here's where it gets curious:
>
> Load.pm:
>
> package Load;
>
> package Bar;
> require './foo.pl';
>
>
> bar.plx:
>
> package Wiff;
>
> use lib '.';
> use Load;
>
> package Wang;
> Bar::_package();
>
>
> foo.pl remains as before. Run that and you get 'Wiff'. Huh?

Although I can't find any supporting documentation, I think that this is
because 'use' is propogating the package into the statement. A little testing
shows that replacing the use Load with require Load reverts the package to
main. Enclosing that statement in an eval makes no odds; however, a require
within a BEGIN does give Wiff as the package: so presumably that is why use
does this. I wouldn't like to say whether that's intentional.

Mx.

Steve Hay

unread,
Apr 15, 2004, 1:07:39 PM4/15/04
to Martyn J. Pearce, Michael Schwern, perl5-...@perl.org
Martyn J. Pearce wrote:

>On Tue, Apr 13, 2004 at 02:49:25PM -0400, Michael Schwern wrote:
>
>
>>foo.pl:
>>
>>sub _package { print __PACKAGE__ }
>>1;
>>
>>
>>bar.plx:
>>
>>package Bar;
>>require './foo.pl';
>>Bar::_package();
>>
>>
>>Why does that print 'main'? By my understanding, __PACKAGE__ is the
>>package that the code was compiled in. If it was compiled in main, why
>>is _package in Bar's symbol table? Bug or feature?
>>
>>
>
>
>I think this is because the effect of 'package' is limited to the current file,
>being the current compilation unit.
>

I thought that too. If that's correct then it would explain why
_package() prints 'main', but the question remains why is _package() in
Bar:: -- shouldn't it be in main::?

Enclosing the 'require' in a BEGIN block removes the inconsistency, but
not in the way that I would expect -- instead of compiling _package()
into main::, it makes the output say 'Bar'.

There seems to be some related strangeness using 'eval' instead of
'require':

package Bar;
eval { sub _package { print __PACKAGE__ } };
Bar::_package();

correctly outputs 'Bar' (because, of course, this time everything *is*
within the scope of the 'package Bar' declaration), but:

package Bar;
eval "sub _package { print __PACKAGE__ }";
Bar::_package();

outputs 'main'.

In each case, if _package() is compiled during the program's compilation
phase (i.e. BEGIN { require FILE } or eval BLOCK) then the output is
consistent (if a little surprising in the former case), but if
_package() doesn't get compiled until the program's execution phase
(i.e. require FILE or eval EXPR) then the output is inconsistent.

- Steve

------------------------------------------------
Radan Computational Ltd.

The information contained in this message and any files transmitted with it are confidential and intended for the addressee(s) only. If you have received this message in error or there are any problems, please notify the sender immediately. The unauthorized use, disclosure, copying or alteration of this message is strictly forbidden. Note that any views or opinions presented in this email are solely those of the author and do not necessarily represent those of Radan Computational Ltd. The recipient(s) of this message should check it and any attached files for viruses: Radan Computational will accept no liability for any damage caused by any virus transmitted by this email.

0 new messages