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

hi,

is there a more delicate way to do this? i have a script that uses a subroutine from a module. example

"Test.pl" use strict; use DBI; use DB qw(:All); use SQL::Abstract; my $sql = SQL::Abstract->new(); my $dbh = DBI -> connect("dbi:SQLite:dbname=test.db", "", "",{RaiseErr +or=>1, AutoCommit=>1}); my $popsamp = [qw(Popl Samp)]; my $form2 = "ID varchar(40) not null"; createtb($form2,$popsamp,$dbh);
and now there is a module that contains subroutine:
package DB; use strict; use base qw(Exporter); use vars qw(@EXPORT_OK); @EXPORT_OK = qw(createtb); sub createtb{ my ($form, $tabler, $dbh) = @_; my @table = @$tabler; foreach my $table (@table){ my $stm = "create table $table ($form)"; my $stm1 = $dbh -> prepare($stm); $stm1 ->execute; } }
now the problem is that i have to pass $dbh variable to a module to work, but this seams very unprofessional(not that i am one). so i was wondering is there some other way to make variable available to the modules of my interest(specificaly a subroutines in the module)

thanx

Replies are listed 'Best First'.
Re: Database module question
by CountZero (Bishop) on Jun 14, 2008 at 15:42 UTC
    i have to pass $dbh variable to a module to work, but this seams very unprofessional

    Not at all! This is the way to do it. You do not want to have your module assume that somewhere else someone else did or did not set a variable. A subroutine should only use variables local to itself and received through the parameter list. I should then return a (list of) value(s) for the caller to pick up and not change some global values.

    The so-called action at a distance will lead to all kinds of nasty and difficult to debug errors.

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: Database module question
by almut (Canon) on Jun 14, 2008 at 15:51 UTC

    There are many ways to do this... One way would be the OO approach, i.e. open the connection when constructing a DB object, and store $dbh as an attribute, which you can always access via the respective DB instance (and thus don't have to pass around). Then you don't even need Exporter and stuff...  For example something like this:

    package DB; use strict; use DBI; sub new { my $class = shift; my $dsn = shift; my $dbh = DBI->connect($dsn, "", "",{RaiseError=>1, AutoCommit=>1} +); return bless { _dbh => $dbh }, $class; } sub dbh { my $self = shift; return $self->{_dbh}; } sub createtb { my ($self, $form, $tabler) = @_; my $dbh = $self->dbh(); # ... } # --- Test.pl use strict; use DB; use SQL::Abstract; my $sql = SQL::Abstract->new(); my $db = DB->new("dbi:SQLite:dbname=test.db"); # ... $db->createtb($form2,$popsamp); # ...
Re: Database module question
by blahblah (Friar) on Jun 14, 2008 at 19:07 UTC
    I asked a very similar thing:

    How to share DBI connections between objects?


    Robert Browning on being asked what some line in one of his poems meant said
    'When I wrote it only God and Robert Browning knew. Now only God knows.'
      It is something that comes up now and then. This is my ramblings on the subject: Re: Querying a $dbh.