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

Hi All I'm trying to write a small collection of CGI scripts for various functions. I'd like to be able to have a seperate file for some config data and subroutines that will be used globally.

I've created the file with DB connection info and some other basic stuff and am using "require ./config.pl" in each of the scripts. The problem is that variable declaration in config.pl aren't avaliable in the other scripts. So after connecteing to the DB using the subroutine in config.pl $dbh and $sth aren't exported. The variables in question are initalised outside the subroutines but are in config.pl.

Also passing variables from the running script into a subroutine in config.pl seems to be impossible too, although I suspect thats all related to a namespace type problem. My understanding was that require effectivly made the files into one long file but apparently not

Replies are listed 'Best First'.
Re: CGI and require
by davido (Cardinal) on May 30, 2004 at 04:09 UTC
    The idea behind packages is that they have their own namespace, and that namespace is neither polluted by, nor can it pollute the namespace of other packages (including package main), by default.

    You want to take things a step further; set up your packages as modules. Your modules can export specific variables and/or subroutines. This is done using theExporter module. Follow the Exporter link to read its documentation. You also need to "use" the module instead of "require" it. require doesn't trigger the export of variables and subs.

    Also be sure to have a look at perlmod to gain a better understanding of modules. You'll find it pretty helpful.


    Dave

Re: CGI and require
by sgifford (Prior) on May 30, 2004 at 04:38 UTC

    The problem is that variable declarations under use strict are checked at compile-time, but require isn't executed until run-time. So the variables aren't yet declared when your code is compiled, and they trigger an error.

    The solution (apart from breaking this out into a module, as davido suggested) is to load the config file before the rest of your code is compiled. You can do this by loading it in a BEGIN block:

    BEGIN { require 'config.pl'; }

    Also, it may be that do 'config.pl' is what you really want; require will only load the config file once, even if you have several modules that are using it. do is closer to an eval, which is what I think of when I'm loading a config file.

Re: CGI and require
by tachyon (Chancellor) on May 30, 2004 at 04:48 UTC

    You really want a module rather than a require as it addresses the issues you are trying to solve. Simple Module Tutorial. For example then you could have a function like:

    use vars '$dbh'; END{ $dbh->disconnect() if $dbh } sub connect { # connect database handle unless we have one already $dbh ||= DBI->connect.... }

    Then in your code you just call connect() whenever and wherever you need a DBH. The first call to it $dbh will be undef so it will get initialized. After that the connect() function just returns the existing DBH. Bonus features include automatically disconnecting and only connecting if you have to.

    cheers

    tachyon

      Thanks to everyone. I've created the module and everything looks good