Frage

Is there any way in perl to import variables from the main script to the module?

Here is my main.pl:

#!/usr/bin/perl -w
use DBI;
our $db = DBI->connect(...);

__END__

Now I want to use the $db variable in my modules, because I want to avoid duplicate connections and duplicate codes... It is possible?

War es hilfreich?

Lösung

You can do that by referring to $main::db in other packages. The main namespace always point to globals in the primary namespace if there is none other given. You should read up on package.


Note that this is not a very good idea as your modules will be dependent on main having the connection. Instead, you should construct your objects in a way that let you pass a database handle in. If you require a db connection at all cost, either let them throw an exception or create their own db handle.

If you are not using OO code, make the database handle an argument of every function call.

Also note that it's best practice to name the database handle $dbh.


Let's look at this for non-OO (Foo) and OO (Bar).

# this is package main (but you don't need to say so)
use strictures;
use DBI;
use Foo;
use Bar;

my $dbh = DBI->connect($dsn);

Foo::frobnicate($dbh, 1, 2)
my $bar = Bar->new(dbh => $dbh);
$bar->frobnicate(23);

package Foo;
use strictures;

sub frobnicate {
  my ($dbh, $one, $two) = @_;

  die q{No dbh given} unless $dbh; # could check ref($dbh)
  $dbh->do( ... );

  return;
}

package Bar;
use strictures;

sub new {
  my ($class, %args) = @_;

  die q{No dbh given} unless $args{dbh};
  return bless \%args, $class;
}

sub frobnicate {
  my ($self, $stuff) = @_;

  $self->{dbh}->do(q{INSERT INTO bar SET baz=?}, undef, $stuff);
  return;
}

__END__

Andere Tipps

You can always pass a db handle into a method. I'm not a fan of this approach, but we have code that functions using this approach.

The problem IMHO is in the debugging. It makes it difficult to know anything about the db handle itself from the code in your module, though that might not be an issue for you. Imagine, however going in to debug code that uses a db handle, but you have no idea where it came from. If you get your db handle from a method in your class, you can trace it to that subroutine and immediately you have some information. This is definitely my preferred way of doing things.

If you do pass in a DB handle, you should do some input validation, such as checking for $dbh->isa('DBI::db') (I think that's the class into which db handles are blessed).

My preference, however would be to have a subroutine in your class that gets the db handle, either based on information you pass in, or by information in the sub itself. One thing to consider is that if you're using DBI, the connect_cached() method is very helpful. From the DBI docs:

connect_cached is like "connect", except that the database handle returned is also stored in a hash associated with the given parameters. If another call is made to connect_cached with the same parameter values, then the corresponding cached $dbh will be returned if it is still valid. The cached database handle is replaced with a new connection if it has been disconnected or if the ping method fails.

Using db handle caching of some sort will, regardless of whether you were to have created the db handle in your script or in the class, give you the same connection.

So, I recommend creating a method in your class that takes all of the parameters required to replicate the creation of the db handle as you'd do it in your script, and consider using connect_cached, Apache2::DBI or something that will handle the db connection pooling/abstraction.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top