Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Importing constants into another module

by paulski (Beadle)
on Feb 03, 2005 at 00:57 UTC ( #427488=perlquestion: print w/replies, xml ) Need Help??

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

I've written a small script which uses a module called Config.pm to read a set of global constants as config file parameters. (Why invent a new config file syntax when you can use what PERL already provides, right?). This works fine. But I want the config file constants available to all the modules in my application. But I can't get this to work. My config module, Audit::Config.pm follows:
# full path to hosts file use constant HOSTS_FILE => '/home/csssec/audit/css_hosts.txt'; # full path to local host binary use constant HOST_BIN => '/usr/bin/host'; ... 1;
Here's the script I'm using to test:
#!/usr/bin/perl -w use strict; use Audit::Config; use Check::DNSCheck; # for every host in the hosts file open(FILE, HOSTS_FILE) || die("$!\n"); while (<FILE>) { chomp($_); my $host = $_; next if ($host =~ /^(\s*)#/); my $chk = new DNSCheck($host); $chk->run(); } close(FILE);
I want Check::DNSCheck to be able to access the constants in Audit::Config as well. I've gotten this to work in a non-OO context. But I changed Check::DNSCheck to be an OO style module (with new{} sub etc) and I could no longer access the constants in Audit::Config. Check::DNSCheck code follows:
package DNSCheck; use Audit::Config; use strict; sub new { my $class = shift; my $host = shift; my $this = { host => $host, }; bless ($this, $class); } sub run { my $this = shift; my $cmd = HOST_BIN . " $this->{'host'} 2>/dev/null"; my $r = `$cmd`; if ($r !~ /has address/) { return(0); } return(1); } 1;
Running gives the following error:
Bareword "HOST_BIN" not allowed while "strict subs" in use at Check/DN +SCheck.pm line 30. Compilation failed in require at ./audit.pl line 6. BEGIN failed--compilation aborted at ./audit.pl line 6.
So Check::DnsCheck.pm obviously insn't importing the values in Audit::Config.pm, but I'm not sure why. Some insight in this would be greatly appreciated.

Is there a better way to go about this?

Thanks

Replies are listed 'Best First'.
Re: Importing constants into another module
by Tanktalus (Canon) on Feb 03, 2005 at 01:03 UTC

    The code we're interested in is actually in Audit::Config. Specifically, look at Exporter - you use Exporter in your exporting module (makes sense), set up an @EXPORT array (I use "our @EXPORT = ...", but that's because I never use an older version of perl where our doesn't exist), and Bob's yer uncle. All other modules that "use Audit::Config;" will automatically get the exported constants.

    I doubt it's making your module OO that made this stop working - it's probably the use strict ;-)

      I thought it was something to do with Exporter before I posted but my attempts to export the constants didn't work. Here's what I've tried:

      Audit::Config.pm:

      package Config; require Exporter; @ISA = qw(Exporter); @EXPORT = qw(HOSTS_FILE HOST_BIN); use constant HOSTS_FILE => '/home/csssec/audit/css_hosts.txt'; use constant HOST_BIN => '/usr/bin/host'; ... 1;
      Check::DNSCheck.pm
      package DNSCheck; use Audit::Config; use strict; sub new { my $class = shift; my $host = shift; my $this = { host => $host, }; bless ($this, $class); } sub run { my $this = shift; my $cmd = HOST_BIN . " $this->{'host'} 2>/dev/null"; my $r = `$cmd`; if ($r !~ /has address/) { return(0); } return(1); } 1;
      I still get the same error message:
      Bareword "HOST_BIN" not allowed while "strict subs" in use at Check/DN +SCheck.pm line 24. Compilation failed in require at ./audit.pl line 6. BEGIN failed--compilation aborted at ./audit.pl line 6.
      I'm sure it's something to do with exporting the constants but as far as I can see, I'm doing it all according to the man page.

      Any ideas?

        You need to use the right namespace in your module. In Audit::Config, make the following change:
        # package Config; package Audit::Config;
Re: Importing constants into another module
by brian_d_foy (Abbot) on Feb 03, 2005 at 01:18 UTC

    You need to export the constants. See, for instance, a module that does it, like Socket. The Exporter module will do all of the work for you once you set the right variables (which Exporter explains).

    use base qw(Exporter); use vars qw(@EXPORT); @EXPORT = qw(HOST_BIN HOST_FILE);
    --
    brian d foy <bdfoy@cpan.org>
Re: Importing constants into another module
by djantzen (Priest) on Feb 03, 2005 at 02:30 UTC

    What's the benefit of exporting these constants? Just call them with the package name prepended like Audit::Config->HOST_BIN. It's more verbose, but it's better OO for reasons of encapsulation, it simplifies your code because you don't have to twiddle with exports, and it advertises to readers of the code exactly where that data is coming from and thereby increases maintainability.


    "The dead do not recognize context" -- Kai, Lexx
      You're right, it's a tradeoff. I could either have more verbose constants, which would clutter up the code (they're used very frequently) and good OO design. Or I could export them all so other modules looks less cluttered but sacrifice maintainability/extensibility in the future.

      Given that this application has a limited lifespan and scope, I'm thinking the latter makes the most sense.

      Feel free to call me insane. :-)

        Thanks for everyone's help. I've got this module stuff down now. :-)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://427488]
Approved by Tanktalus
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others taking refuge in the Monastery: (4)
As of 2020-07-09 11:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?