mje has asked for the wisdom of the Perl Monks concerning the following question:

Hello monks, I'm having no luck trying to access constants defined and exported in one module to a lower level module:
MyMod.pm ======== use strict; use warnings; package MyMod; use Exporter (); use vars qw (@EXPORT @EXPORT_OK); use constant MYMOD_DEFAULT => 1; BEGIN { @EXPORT = (); @EXPORT_OK = (MYMOD_DEFAULT); }; use MyMod::db; 1; MyMod/db.pm =========== use strict; use warnings; package MyMod::db; sub fred { print "hello" if (MYMOD_DEFAULT); } 1;
perl -cw MyMod.pm

Bareword "MYMOD_DEFAULT" not allowed while "strict subs" in use at MyMod/db.pm line 5. Compilation failed in require at MyMod.pm line 12. BEGIN failed--compilation aborted at MyMod.pm line 12.

I saw the thread at http://www.perlmonks.org/?node_id=384405 and the answer by ysth sounded like it worked but I cannot make it work for me.

Hope you can help.

Replies are listed 'Best First'.
Re: Can't import constants in multiple namespaces
by xdg (Monsignor) on Mar 28, 2006 at 12:16 UTC
    defined and exported in one module to a lower level module

    You should be aware that the notion of "lower level" doesn't matter for this kind of thing. While there is a hierarchy of namespaces, Perl doesn't automatically do anything with it. Nothing is exported to lower levels by default. Likewise, lower levels do not inherit methods from upper levels. The hierarchy is entirely a convenience for users.

    As Joost said, you have to "use" the module at the lower level for it to work. Likewise, for object oriented programming, you have to "use base" or otherwise set the @ISA array.

    package My::Class; sub foo { print "Foo" } 1;
    package My::Class::Reversed; use base qw( My::Class ); sub foo { print reverse "Foo" } 1;

    -xdg

    Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

      Thanks - some stuff got lost in an attempt to simplify my problem for posting. I'm still not there and am now using:
      use strict; use warnings; package MyMod; use Exporter (); use MyMod::db; use vars qw (@EXPORT @EXPORT_OK); use constant MYMOD_DEFAULT => 1; BEGIN { @EXPORT = (qw(MYMOD_DEFAULT)); #@EXPORT_OK = (qw(MYMOD_DEFAULT)); }; 1; use strict; use warnings; package MyMod::db; # I also tried use MyMod qw(MYMOD_DEFAULT) when constant was # in EXPORT_OK and not EXPORT. use base qw(MyMod); sub fred { print "hello" if (MYMOD_DEFAULT); } 1;

      Bareword "MYMOD_DEFAULT" not allowed while "strict subs" in use at MyMod/db.pm line 6. Compilation failed in require at MyMod.pm line 5. BEGIN failed--compilation aborted at MyMod.pm line 5. My original (before simplification) was using EXPORT_TAGS.

        I guess we're all reading these a little too fast. And I think I confused you with my comment about OO and use base. You don't need that for what you're doing, though you do need it for Exporter which we overlooked before.

        Here's an annotated version of something that should work. I've reordered/simplified lines for clarity. For example, you don't really need the BEGIN block and assuming you're using Perl 5.6 or later, you can replace all the use vars with our.

        # MyMod.pm use strict; use warnings; package MyMod; use constant MYMOD_DEFAULT => 1; use base qw( Exporter ); # You need to subclass Exporter our @EXPORT = qw( MYMOD_DEFAULT ); # No extra parens needed 1;
        # MyMod/db.pm use strict; use warnings; package MyMod::db; use MyMod; # imports MYMOD_DEFAULT automatically sub fred { print "hello" if (MYMOD_DEFAULT); } 1;
        # fred.pl use strict; use warnings; use MyMod::db; MyMod::db::fred(); # fully qualified call

        Output of fred.pl:

        hello

        -xdg

        Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.

Re: Can't import constants in multiple namespaces
by Joost (Canon) on Mar 28, 2006 at 12:07 UTC
      I tried:
      use strict; use warnings; package MyMod::db; use MyMod; sub fred { print "hello" if (MYMOD_DEFAULT); } 1;

      but now I get:

      Constant subroutine MyMod::MYMOD_DEFAULT redefined at /usr/local/lib/perl5/5.8.7/constant.pm line 103. Bareword "MYMOD_DEFAULT" not allowed while "strict subs" in use at MyMod/db.pm line 6. Compilation failed in require at MyMod.pm line 12. BEGIN failed--compilation aborted at MyMod.pm line 12.

        You need to quote MYMOD_DEFAULT for @EXPORT_OK

        @EXPORT_OK = ( 'MYMOD_DEFAULT' ); # or qw( MYMOD_DEFAULT )

        Also, when you "use" it, you'll need to ask for it, as you put it in EXPORT_OK, not EXPORT.

        use MyMod qw( MYMOD_DEFAULT );

        -xdg

        Code written by xdg and posted on PerlMonks is public domain. It is provided as is with no warranties, express or implied, of any kind. Posted code may not have been tested. Use of posted code is at your own risk.