in reply to Re: Can't import constants in multiple namespaces
in thread Can't import constants in multiple namespaces

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.

Replies are listed 'Best First'.
Re^3: Can't import constants in multiple namespaces
by xdg (Monsignor) on Mar 28, 2006 at 13:43 UTC

    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.

      Thanks, that does in deed work but it has strayed a somewhat from what I was trying to do which is probably because I tried to simplify too much. I am actually trying to subclass Perl DBI so I need:
      DBIx::MyMod DBIx::MyMod::db DBIx::MyMod::st
      The user of DBIx::MyMod does
      use DBIx::MyMod qw(MYMOD_CONSTANT); # connect in the root my $h = DBIx::MyMod->connect(x,y, {XXX => MYMOD_CONSTANT});

      I override connect in DBIx::MyMod and other DBI methods in DBIx::MyMod::db and DBIx::MyMod::st. I want to define and export the constants in DBIx::MyMod but still use them in DBIx::MyMod::db. I believe this would be equivalent to your fred.pl and the previous MyMod example doing:

      fred.pl use MyMod; # assuming all constants in EXPORT MyMod::db->fred();
      and
      use strict; use warnings; package MyMod; use MyMod::db; use constant MYMOD_DEFAULT => 1; use base qw (Exporter); our @EXPORT = qw(MYMOD_DEFAULT); 1;
      use strict; use warnings; package MyMod::db; use MyMod; sub fred { print "hello" if (MYMOD_DEFAULT); } 1;

      Do you know if it is possible to make that work?

        Thanks to all. The solution which worked (avoiding the MyMod::MYMOD_DEFAULT redefined at /usr/local/lib/perl5/5.8.7/constant.pm message and allowing the constant to be seen "above" and "below" the module which defined it was:
        fred.pl use MyMod; MyMod::db->fred(MYMOD_DEFAULT);
        MyMod.pm use strict; use warnings; package MyMod; use constant MYMOD_DEFAULT => 1; use Exporter qw(import); our @EXPORT = qw (MYMOD_DEFAULT); # changing the use to require did the trick: require MyMod::db; sub dave { print "The constant is ", $_[1], "\n"; } 1;
        MyMod/db.pm use strict; use warnings; package MyMod::db; use MyMod; sub fred { print "hello\n" if (MYMOD_DEFAULT); } 1;

        Just be careful not to create circular dependencies. MyMod uses MyMod::db and vice versa. That's likely to cause trouble. Instead, refactor all your constants to MyMod::constants and use that in MyMod and MyMod::db. In MyMod you can import from MyMod::constants and still re-export them in @MyMod::EXPORT.

        -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.