in reply to Using packages to store global configuration vars

You're missing two things:

1. As already mentioned, my vars are only visible within the same scope, pretty much no matter what you do. Use our instead if you want them to be visible in other packages or files.

2. Just changing my to our will allow you to reference the variables from your main program as $Config::database. If you want to be able to use just $database in the main program, then the Config module will need to export them, using Exporter:

package Config; use strict; use warnings; use base 'Exporter'; BEGIN { # Things to export by default - minimize this, if you use it at all our @EXPORT = qw( ); # Things to export when the calling code requests them our @EXPORT_OK = qw( \$database \$tmplfile \$blog_title ); # A handy way of grouping exported items our %EXPORT_TAGS = ( all => [ @EXPORT, @EXPORT_OK ] ); } our $database = 'data/site.db'; our $tmplfile = 'templates/index.html'; our $blog_title = 'example.com'; 1;
The main program, then, would start off with
#!/path/to/perl use strict; use warnings; use lib qw(/var/www/blogapp); use Config qw($database, $tmplfile, $blog_name); # or just # use Config qw(:all); # if you want everything the Config module exports

Replies are listed 'Best First'.
Re^2: Using packages to store global configuration vars
by fuzzyping (Chaplain) on Sep 06, 2009 at 13:34 UTC

    I tried using Exporter as you described above (great example, thanks) but Apache/mod_perl kept complaining that :all wasn't being exported.

    I gave up on this after a while and am trying to simply use our and call the vars with $Config::var. I'm getting the same error as before and there are no values associated with the variables. I added a print STDERR "database is $Config::database\n"; to demonstrate.

    Snippet from Config.pm:

    package Config.pm; use strict; ########################### # user options # ########################### our $database = 'data/site.db'; our $tmplfile = 'templates/index.html';

    A couple snippets from index.cgi:

    use strict; my $database = $Config::database; my $tmplfile = $Config::tmplfile; ... print STDERR "FOOBAR $Config::database\n"; my $template = HTML::Template->new(filename => $tmplfile, die_on_bad_p +arams => 0);

    And the error:

    FOOBAR [Sun Sep 6 05:30:35 2009] [error] PerlRun: `HTML::Template->new() cal +led with odd number of option pa rameters - should be of the form option => value at /blogapp/index.cgi + line 29\n'
    -fp
      The first possibility that comes to mind is that you may not have restarted apache. One of the disadvantages of mod_perl development is that it doesn't check for changes to your code, so it's likely to still be running the original version if you haven't. (There is a switch you can set in httpd.conf which helps with this, but I don't recall the incantation offhand.)

      The second is that, in your original question, you said you had use Config at "The tail end of [your] startup.pl". Unless something else has caused Config.pm to be loaded earlier in your startup process, the perl compiler won't know about anything from Config until it hits that use line. Move use Config up towards the top of your code, so that it appears before any references to the variables in Config.pm, and it should take care of that problem.

      If neither of those things resolves your problem, try stripping both startup.pl and Config.pm down to the bare minimum necessary to demonstrate the issue and post them in full (not just snippets) so that we can see exactly what's going on. Unless, that is, you find a solution while you're in the process of creating your minimum failing case...

        I always restart Apache so that's not the problem. Here are the full contents of startup.pl and Config.pm as well as the first 20 or so lines of index.cgi.

        Contents of startup.pl:

        use lib qw(/var/www/blogapp); use Config (); use CGI; use DBI; use DBD::SQLite; use HTML::Template; use XML::RSS; use Net::SMTP; use Captcha::reCAPTCHA; use HTML::Entities; use HTTP::Request::Common; use URI::_foreign; use Errno; use Net::HTTP; use IO::Select; use Compress::Zlib; use Log::Agent; use URI::http; use LWP::Protocol::http; use Carp::Heavy; 1;

        Contents of Config.pm:

        package Config.pm; use strict; our $database = 'data/site.db'; our $tmplfile = 'templates/index.html'; our $blog_title = 'example.com'; our $blog_subtitle = 'My New Blog'; our $blog_url = 'http://www.example.com/'; our $blog_owner = 'user@example.com'; our $blog_rights = 'Copyright 2009, Example User'; our $feed_updates = 'hourly'; our $captcha_pubkey = ''; our $captcha_seckey = ''; our $comment_max_length = '1000'; our $comments_allowed = 0; our $smtp_server = 'localhost:25'; our $smtp_sender = 'blogapp@example.com'; 1;

        First ~20 lines of index.cgi:

        use strict; my $database = $Config::database; my $tmplfile = $Config::tmplfile; my $blog_title = $Config::blog_title; my $blog_subtitle = $Config::blog_subtitle; my $blog_url = $Config::blog_url; my $blog_owner = $Config::blog_owner; my $blog_rights = $Config::blog_rights; my $feed_updates = $Config::feed_updates; my $captcha_pubkey = $Config::captcha_pubkey; my $captcha_seckey = $Config::captcha_seckey; my $comment_max_length = $Config::comment_max_length; my $comments_allowed = $Config::comments_allowed; my $smtp_server = $Config::smtp_server; my $smtp_sender = $Config::smtp_sender; my $cgi = CGI->new; my $dbh = DBI->connect("DBI:SQLite:dbname=$database", '', '', { RaiseE +rror => 1 }) || die $DBI::errstr ; print STDERR "FOOBAR $Config::blog_title\n"; my $template = HTML::Template->new(filename => $tmplfile, die_on_bad_p +arams => 0);
        -fp
      Most likely you're calling the core module Config, you should adjust your @INC path accordingly.

      UPDATE: ...or just rename your configuration file and package .

      Cheers Rolf

        That was it! Thanks for the pointer. I think I'll try Exporter again now. :)

        -fp