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

I have a new project I'm working on, and I'm tinkering with OOP for variable storing (I could just use hashes, but I'm wanting to learn more about OOP). The problem is, it's a database application, and I want to keep the work perl has to do to a minimum.

I've got 2 packages in separate pm modules so far: TArtLib and TArt::Editor (it's for TalkArticles... TArt seemed cute :P). TArtLib holds a $dbh database connection handle and uses DBI. TArt::Editor is just a data object with accessor methods. What I want is for my TArt::Editor to use the DBI connection ($TArtLib::dbh) from the TArtLib program, so it doesn't have to use DBI and make the connection for every Editor Data object I create. That way TArt::Editor can populate itself with the data for an editor by itself, instead of having arguments passed to it to populate them.

package main; use TArtLib; use TArt::Editor; my $lib = new TArtLib; # This object would populate itself from the database, # using the number passed to it as the primary key, # and hopefully using TArtLib's DBI connection. my $ed = new TArt::Editor(1); print $ed->{NAME}; # etc. etc.
I know Apache::DBI will keep the DB connections going (It's running in mod_perl), but I'm wanting it to do it from the command line as well. I'm just not sure how to get TArt::Editor to get TArtLib's DBI connection. BTW, TArtLib will always be called before TArt::Editor, if that helps.

Replies are listed 'Best First'.
Re: OOP Access of variables
by TheoPetersen (Priest) on Mar 08, 2001 at 21:27 UTC
    The usual way would be to store the dbh in a package variable and have a method for it, i.e.
    package TArtLib; use strict; use vars qw($dbh); ... sub dbh { return $dbh; }
    Then TArt::Editor invokes the method:
    package TArt::Editor; use TArtLib; ... my $dbh = TArtLib->dbh;
    Note the usage of TArtLib inside of TArt::Editor; that relieves the code which calls TArt::Editor from knowing what other modules are required.

    The dbh class method would also be a good place to initialize things (or call an initialization method) if $dbh is false.

    Update:If what you want is one-time initialization, then this is definitely the way to go. Don't use the package $dbh directly, but go through a method as shown here; and use that method to do the one-time initialization:

    sub dbh { unless ($dbh) { # connect to the database now. } return $dbh; }
      Theo: Thanks, that's a good idea. I just have another question:

      If I also have a TArt::Article package data object, and I call the script like this:

      package main; use TArt::Editor; use TArt::Article; my $ed = new TArt::Editor; my $art = new TArt::Article;
      If both of these packages (TArt::Editor, TArt::Article) use TArtLib, would they both get the same $dbh object when calling TArtLib->dbh, or would it be two separate TArtLib packages (and thus, two database handle objects)?
        Assuming the code I gave you, there would be only one $dbh. (Hey, that's a catchy phrase ... :)

        When learning Perl objects (or Perl anything else), follow your hunches and try them out. You'll develop both knowledge and intuition quickly. That's the nice thing about Perl's learning curve, you can almost always do useful work along the way.

Re: OOP Access of variables
by Masem (Monsignor) on Mar 08, 2001 at 21:22 UTC
    I think I'm missing something here, but isn't this as easy as making sure that TartLib's dbi connection variable is in the EXPORT list, or you provide a function that returns it if you want better encapsulation?: eg...
    my $sth = TArtLib::dbi->prepare("select * from table") or die DBI::err +str; my $sth2 = TArtLib->dbi()->prepare("select * from table") or die DBI:: +errstr;
    What's confusing is that you say you want it from the persistent connection from the command line as you'd get from running Apache::DBI. Unless you have an aspect of your program that will be running constantly acting as a server, I don't see how you can get this, as TArtLib will be initialized every runtime from the command line, reconnecting it to the database. Maybe I'm just mistaken here.
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
      Sorry, I must not have made it clear.

      I mean, each time the main script is run, I only want one instance of the database connection. This is created in TArtLib ($TArtLib::dbh).

      I want TArt::Editor to be able to use $TArtLib::dbh, so that TArt::Editor doesn't need to make a new DB connection. Both TArtLib and TArt::Editor will/should always be used in package main.

        ... the reason being, if I have 40 editor objects, I don't want 40 database handles. I'd like all 40 TArt::Editor objects to use TArtLib's DB connection.