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

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.

Replies are listed 'Best First'.
Re^4: Can't import constants in multiple namespaces
by mje (Curate) on Mar 28, 2006 at 14:53 UTC
    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.

        Yes, I had tried that as a solution and I agree it is better but I could not understand why I could not make it work as it was. Thanks again for the help.