http://www.perlmonks.org?node_id=93382

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

Hi, I've got two programs, lets say "main.cgi" and "commons.pl". The "commons.pl" program contains all of the globably declared variables and subroutines that are used by all the other various programs, including "main.cgi".

In the commons file, I also have my "use" statements.

#!/usr/bin/perl use DBI; use Date::Calc qw( Decode_Date_US Add_Delta_Days); use File::Copy; use LWP::Simple; use CGI::Carp 'fatalsToBrowser'; use CGI qw/:standard/; $q = new CGI; my $variables; etc...
From the "main" program, I'm accessing this large group of subroutine and variable by using:
#!/usr/bin/perl require ("commons.pl"); rest of program here...
Now, the problem is that I'm getting "Prototype mismatch: sub main::head ($) vs none at /usr/local/lib/perl5/5.00502/CGI.pm line 232." errors everytime I run the script.

I've tried to define the "commons" as a .pm and "use commons", but then I get errors like "Undefined subroutine CGI::"

So, the question is how do I create a package of common variables, arrays, hashes, and subroutines in one file that I can call either through require or use and have them available to all my other programs.
--
Filmo the Klown

Replies are listed 'Best First'.
(bbfu) Re: Prototype mismatch error
by bbfu (Curate) on Jul 03, 2001 at 12:12 UTC

    The most likely cause of the prototype mismatch errors is that require happens at run-time, which is long after prototypes checks are applied. You need to force the require to happen at compile time by putting it in a BEGIN block:

    BEGIN { require 'commons.pl' }

    For the uses in commons.pl to work properly, you should make sure that they are executed with package main:

    # in commons.pl... package main; use DBI; use Date::Calc qw( Decode_Date_US Add_Delta_Days); use File::Copy; # etc.

    Unfortunately, you can't use lexical variables at all this way since they are file scoped, not package scoped. You'll have to use package variables instead, and predeclare them in main.cgi:

    # in main.cgi... our $q, $variables; # or, for < 5.6: #use vars qw/$q $variables/; BEGIN { require 'commons.pl' }

    # in commons.pl, _AFTER_ package main LINE! our $q = new CGI; our $variables; # etc.

    Hope that helps. :-)

    bbfu
    Seasons don't fear The Reaper.
    Nor do the wind, the sun, and the rain.
    We can be like they are.

Re: Prototype mismatch error
by Zaxo (Archbishop) on Jul 03, 2001 at 05:37 UTC

    Try enclosing your common data structures in a package Common; namespace and referring to them as $Common::foo. This will be handier if you rename 'common.pl' to 'Common.pm'.

    Data from a require'd lib is out of scope in the calling file. You may not want to have Common do all your use $module;-ing unless you make it an OO module which inherits from them.

    After Compline,
    Zaxo