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

The scenario:
# a subroutine returns a ref to a database handle... my $pdb = &openDatabase(); # the ref to the db handle is passed to a subroutine as an # optional hash element... &doSomething(DB=>$pdb,FOO=>'bar'); # the subroutine assigns the ref to a scalar if it was # passed, or directly obtains one of its own if it wasn't, # does its thing, then closes the db handle if # it opened it... sub doSomething { my(%param)=@_; # we assign the ref to $rdb if it's defined, or open the # database for the first time if it's not my ($rdb) = ((defined($param{'DB'})) && ($param{'DB'})) ? $param{'DB +'} : &openDatabase(); # the subroutine does something useful... $$rdb->disconnect if(!(defined($param{'DB'}))); return('done'); }
The question: Am I setting myself up for any weird side effects by potentially confusing the reference counter, or am I safe?
  • Comment on lifetime of refs to DBI handles passed to sub as hash elements and assigned to scalar within it
  • Download Code

Replies are listed 'Best First'.
Re: lifetime of refs to DBI handles passed to sub as hash elements and assigned to scalar within it
by dragonchild (Archbishop) on Aug 30, 2001 at 22:18 UTC
    You're fine. The ref goes out of scope and the reference counter goes to 0.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Vote paco for President!

Re: lifetime of refs to DBI handles passed to sub as hash elements and assigned to scalar within it
by VSarkiss (Monsignor) on Aug 30, 2001 at 22:44 UTC

    I think you're fine as far as passing the ref, but there are a couple of other style points that may bite you later.

    • Don't make a habit of calling subs with the &. You're better off doing:
      my $pdb = openDatabase(); # ... doSomething(DB => $pdb, FOO => 'bar');
      The reason is that one day you'll forget the parentheses and be surprised at the fact that Perl did not set up @_ separately. (For more details, take a look at perlman:perlsub.)
    • Your parenthese make the gist of your code hard to see. You can render the test for the DB parameter more idiomatically: my ($rdb) = $param{DB} || openDatabase();Similarly for your final test (from this snippet, it looks like the test isn't even necessary): $rdb->disconnect() unless $param{DB};

    HTH

      People are divided on whether or not to use &. While you are right that you can forget parentheses, you can also get bitten by naming your function with a built-in name.

      And if you don't use &, then there are arguments about using parentheses. If you don't use them and you use strict.pm, then for the cost of having to predeclare functions you get typo checking on your functions. Of course then you have to worry about precedence errors and people misunderstanding you.

      Personally I don't use & and do use parentheses. But I wouldn't say that that choice is the One True Rule that everyone should follow...

Re: lifetime of refs to DBI handles passed to sub as hash elements and assigned to scalar within it
by runrig (Abbot) on Aug 30, 2001 at 22:29 UTC
    Your question ask already been answered, but if you don't mind nitpickiness, you can simplify this line:
    my ($rdb) = ((defined($param{'DB'})) && ($param{'DB'})) ? $param{'DB'} + : &openDatabase(); # to this: (BTW, Don't put parens around 'my' lvalues # unless you want list context...) my $rdb = $param{'DB'} || &openDatabase();