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

Hi all, I have a bit of code in a file db.cgi:
package SUBS; require 'SUBS.pm'; use strict; my($dbh, $sth, $fault_no, @dbinfo, $base, $line); $base = "/path/to/loginfile"; &connectdb();
where the contents of sub connectdb are contained in a seperate file SUBS.pm. The contents of that file are:
package SUBS; require Exporter; @ISA = qw(Exporter); @EXPORT = qw( &connectdb ); use strict; #Open the Oracle database: if (!defined(open(DBINFO, "$base/dbinfo"))) { die "Can't open dbinfo.\n"; } while(defined($line = <DBINFO>)) { chomp($line); push @dbinfo, $line; } close(DBINFO); $dbh = DBI->connect($dbinfo[0],$dbinfo[1],$dbinfo[2],$dbinfo[3], { RaiseError => 1, AutoCommit => 1} ); }
Now when I run db.cgi, I'm getting the following for all the variables in &connectdb:
Global symbol "$var" requires explicit package name at SUBS.pm line ...
So my question is this: if I have declared global variables in db.cgi, why can't SUBS.pm see them? Many thanks in replying... Stacy.

Replies are listed 'Best First'.
Re: using modules
by Fletch (Bishop) on Nov 09, 2001 at 17:26 UTC

    It's complaining because you haven't declared any variables. my'd variables outside of any blocks or subs have a file scope (they're visible to any code in the same file that occurs after them).

    Also you've got a misconception about how Exporter works. You need to actually define a subroutine named connectdb, not just have the code sitting in the file. And to have things exported into your namespace you have to use use, not require (the latter doesn't call the package's import method which is what does the twiddling). Read perldoc perlsub and perldoc perlmod.

      Opps, I do have the sub connect defined, I just didn't type my original post out properly. I have SUBS.pm as:
      sub connectdb { #Open the Oracle database: if (!defined(open(DBINFO, "$base/dbinfo"))) { die "Can't open dbinfo.\n"; } while(defined($line = <DBINFO>)) { chomp($line); push @dbinfo, $line; } close(DBINFO); $dbh = DBI->connect($dbinfo[0],$dbinfo[1],$dbinfo[2],$dbinfo[3], { RaiseError => 1, AutoCommit => 1} ); }
Re: using modules
by davorg (Chancellor) on Nov 09, 2001 at 17:33 UTC

    As Fletch says, your my variables are invisible outside the file that they are declared in. You probably want to declare package variables with use vars or our.

    Also, why are you putting all of your db.cgi code into the SUBS package? Looks like you should re-read perlmod.

    --
    <http://www.dave.org.uk>

    "The first rule of Perl club is you don't talk about Perl club."

      Thank you all for your help. The reason why I'm putting a bit of code into the SUBS package is that I've got about 5 different CGI scripts which get information out of SUBS - it saves me repeating alot of code. My solution was as follows. In SUBS:
      package SUBS; use Exporter; @ISA = qw(Exporter); @EXPORT = qw ($log $site $base $dbh); use vars qw ($log $site $base $dbh); sub connectdb() { #Open the Oracle database: my($dbline,@dbinfo); if (!defined(open(DBINFO, "$base/dbinfo"))) { die "Can't open dbinfo.\n"; } while(defined($dbline = <DBINFO>)) { chomp($dbline); push @dbinfo, $dbline; } close(DBINFO); $dbh = DBI->connect($dbinfo[0],$dbinfo[1], $dbinfo[2],$dbinfo[3], { RaiseError => 1, AutoCommit => 1} ); $dbh->trace(2,"$log"); }
      While in db.cgi:
      package SUBS; use SUBS; . . . &connect_db();
      The main difference betwee this example and my original post was that I am now using use SUBS as opposed to require SUBS as before. I'm also using 'use var'. SUBS also now exports only those variables used by db.cgi in the @EXPORT array. Again, thanks for all your suggestions.
      Stacy.

        I'm still not convinced that the use SUBS statement in db.cgi is doing anything useful. Try removing it and seeing if anything breaks.

        --
        <http://www.dave.org.uk>

        "The first rule of Perl club is you don't talk about Perl club."

Re (tilly) 1: using modules
by tilly (Archbishop) on Nov 09, 2001 at 20:32 UTC
    A side comment based on experience.

    Exporter recommends that you use @EXPORT_OK and explicit import lists rather than using @EXPORT. That suggestion is right on the target. When you are debugging, it is really good if the code you are working with is very explicit about where everything you see is to be found. Using @EXPORT may seem more convenient, but it is a convenience that loses you time and energy in the long run.