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

I have a daemon process that forks children. The code looks approximately like this (I'm omitting the parts that I think are irrelevant, but let me know if I shouldn't have done that.

use strict; start_daemon(); # this runs Proc::Daemon::Init() and sets up some SIG +stuff my $dbh = DBI->new(...); for(0..5){ my $pid = fork(); if ($pid) { next; } # Parent process: create the next child # Child: clone dbh, then do stuff my $childdbh = $dbh->clone(); $dbh->{InactiveDestroy}=1; undef $dbh; # Do stuff for(0..10){ subroutine($childdbh, @somevalues); } exit; # End of the child. } # Parent stuff goes here # Subroutines sub subroutine { my $childdbh = shift; $childdbh->do('this'); $childdbh->do('that'); $childdbh->do('the other'); another_subroutine( $childdbh, @othervalues ); } sub another_subroutine { my $childdbh = shift; $childdbh->do('even more stuff'); }

Ok, sorry about that long intro. My question is: what is the best practice for passing $childdbh to the subroutines? It seems awfully clunky to do it the way I've been doing it (where the first variable passed to any subroutine is the database handler). It works, but this is Perl -- there *must* be a more elegant way of doing it. :)

Replies are listed 'Best First'.
Re: Best practices for passing $dbh to subroutines
by choroba (Cardinal) on Jan 26, 2014 at 09:33 UTC
    If lots of functions require the same parameter(s), think "objects". Just write a package that stores the DB handle. You can then have finer control over the possible actions (i.e., instead of $self->db->do('that'), you can define methods like $self->this; $self->that etc.)
    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
      Of course, every method call gets implicitly the object as its first parameter. In this case the database handle is the explicit first parameter.

      Same same but different.

      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

      My blog: Imperial Deltronics
        I usually store the handle somewhere deeper in the object, with prepared selects or inserts around. So, the methods look like:
        sub add_numbers { my ($self, @params) = @_; $self->{insert_num}->execute(@params); } sub vacuum { my $self = shift; $self->{db}->do('vacuum'); }
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Best practices for passing $dbh to subroutines (subroutine arguments)
by Anonymous Monk on Jan 26, 2014 at 09:02 UTC

    It seems awfully clunky to do it the way I've been doing it (where the first variable passed to any subroutine is the database handler). It works, but this is Perl -- there *must* be a more elegant way of doing it. :)

    um, not really :) that is about as elegant as you should get with one variable

    If you've got more pass a "hash"

    foo( dbh => $dbh, roshambo => 'dynamite'} ); ... sub foo { my %args = @_; $args{dbh}->prepare...; }

    chromatics free book Modern Perl talks about this (%parameters)

    OTOH, there are things like Sub::NamedParams/Params::Named/Method::Signatures...

Re: Best practices for passing $dbh to subroutines
by McA (Priest) on Jan 26, 2014 at 17:22 UTC

    Hi,

    there was a similar thread at Global or not global. Unfortunaltely it drifted too much into a discussion about logging, which is also one of these "we need it almost everywhere services". I really hoped the discussion would go a little deeper about the pros and cons of several architectures. But there may be some valueable hints from some well known monks.

    Best regards
    McA