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

I frequently use DBI in my scripts. Some are quick and dirty scripts, others have the potential to be around for years.

As a matter of habit, I create my database connection early in the script and pass it as an argument to any subroutine that needs it rather than leaving it as a global. This is more a result of my preference to see a list of variables (from the parent) that will be used in the sub than anything else. Which brings me to my question:

Is this simply a matter of style, or are there substantive differences between using a global versus a locally scoped variable. For those of you who also use DBI heavily, how do you maintain your db handle? I try to stay away from globals because I find they make code hard for me to read ("where did THAT come from, and what the heck is it?!"). Are there reasons I shouldn't be passing a $dbh around that I never intend to modify?

Replies are listed 'Best First'.
Re: DBI, $dbh, and subroutines
by GrandFather (Saint) on Jul 12, 2009 at 03:45 UTC

    Your current practise is exactly what is recommended and for just the reasons you give.

    There is no need to worry about any 'overhead' issues in passing the db handle around - it is a scalar reference to a blessed object so all you are really passing around is essentially the address of the 'real' object.

    Depending on context, in a situation where I have a number of related variables I'm inclined to use a light weight object. Consider:

    use strict; use warnings; my %stuff = ( this => 'this important parameter', that => 'that important parameter', dbh => 'the all important database handle', ); my $obj = bless \%stuff; $obj->DoThis ('params', 'as', 'required'); sub DoThis { my ($self, $params, $as, $required) = @_; print "$self->{this} and $self->{that} and $params $as $required\n +"; }

    True laziness is hard work
      GrandFather says it very well. The only other reason I would add is re-use. At some point, the 'only' db handle that you use will most likely turn into more than one. At that point, you will probably want to use many of the same routines you already have. This will obviously be easier when the handle is passed into those routines.


Re: DBI, $dbh, and subroutines
by LanX (Sage) on Jul 12, 2009 at 03:57 UTC
    I'm an advocate of DRY, passing it around increases the error probability , e.g. typos.

    OTOH globals tend to have a problem, if the line distance between creation and usage gets to big, or generally if scope and context are not easy to oversee.

    I'd use a block scope to simulate an object², the "global" is used like a class-attribute.

    { my $global="whatever"; sub method1 { ...; foo($global); ... } sub method2 { ...; bar($global); ... } sub ... }

    Closures are in most simple cases more elegant than objects, especially in perl¹!

    (they just can't inherit, but that's not a "simple" case anymore).

    Cheers Rolf


    (¹) just compare to grandfathers lightweight object! No blessing, no $self ...

    (²) "encapsulation" to be more precise

Re: DBI, $dbh, and subroutines
by FloydATC (Deacon) on Jul 12, 2009 at 07:12 UTC
    Passing it around is a good habit because it will serve you well when re-using your code in places where global variables are a bad idea, such as mod_perl and in modules.

    Still, there's no rule without exceptions. I don't think anyone actually follows all of their own rules when doing quick-and-dirty hacks. That's what make them dirty, right?

    -- Time flies when you don't know what you're doing
Re: DBI, $dbh, and subroutines
by jbt (Chaplain) on Jul 12, 2009 at 03:51 UTC
    I usually wrap the handle in a structure or class. My quick and dirty scripts usually last longer than intended.