On Jul 13, Scott R. Godin said:
The original object itself is at http://www.webdragon.net/miscel/Subscriber.pm
(the Subscriber::DB object will need $database, $username, $password, a DBI
$dbh handle, and possibly a $hostname as well, in addition to the data stored
in the Subscriber object, that I wish to make persistent by storing and
retrieving it from the mysql database. )
The first thing you need to do is figure out the mapping from the old
methods to the new methods.
One gripe I have with Subscriber.pm is that you can't set fields after the
new() method, without knowing the construction of the object. It'd be
nice to have a set_XXX() method which set the field to a given value. You
could do this with AUTOLOAD and it'd be magic:
AUTOLOAD {
my $obj = shift;
(my $method = $AUTOLOAD) =~ s/.*:://;
if ($method =~ /^set(_\w+)/) {
$obj->{$1} = shift;
}
else {
die "no such method '$method'"
}
}
Then you could do
my $who = Subscriber->new;
$who->set_zipcode('08536');
Or you could have a set() method:
sub set {
my $self = shift;
while (@_) {
my ($field, $value) = @_;
if (exists $self->{$field}) { $self->{$field} = $value }
else { die "no such field '$field'" }
}
}
Maybe you'd want to warn() there instead of die(), I don't know. The
point is, then you could write:
my $person = Subscriber->new;
$person->set(
_firstname => "Jeff",
_lastname => "Pinyan",
);
All Subscriber::DB objects would share the DBI object -- there's no need
for a billion database handles. I would also make Subscriber::DB inherit
from Subscriber... for a reason I'll show you in a moment.
If you're making a NEW object (that is, not loading from the DB), perhaps
you should make that the function of the 'new' method, and leave restoring
objects from the DB to a different method, such as 'load' or 'restore'.
my $x = Subscriber::DB->new(fname => "Jean", lname => "Valjean");
# vs.
my $y = Subscriber::DB->load(id => 24601);
# or
my $y = Subscriber::DB->new_from_id(24601);
These objects themselves should be hollow -- that is, they should only
contain as much as is needed to retrieve their data from the database. In
your case, I would guess that means just their id.
Then, when you do $y->get_greeting(), perhaps you want to do something
like:
# here's a global variable for all of Subscriber::DB
my $greeting_sql = $DBH->prepare(q{
SELECT salutation, firstname, lastname
FROM subscriber_db
WHERE id = ?
});
# Subscriber::DB::get_greeting
sub get_greeting {
my ($self) = @_;
my $id = $self->{_id};
$greeting_sql->bind_columns(
\$self->{_salutation},
\$self->{_firstname},
\$self->{_lastname},
);
$greeting_sql->execute($id);
# now here is the magic!
return $self->SUPER::get_greeting;
}
This is where the inheritence counts. Subscriber::DB::get_greeting merely
populates enough of the hash for Subscriber::get_greeting to operate
correctly. The bind_columns() call tells the SQL statement to populate
those values (values in a hash) when it gets executed.
Now, if you had your Subscriber::AUTOLOAD set up, we could rewrite this
as:
sub get_greeting {
my ($self) = @_;
my $id = $self->{_id};
$greeting_sql->bind_columns(\my ($salut, $fname, $lname));
$greeting_sql->execute($id);
$self->set_salutation($salut);
$self->set_firstname($fname);
$self->set_lastname($lname);
# magic as usual
return $self->SUPER::get_greeting;
}
*OR*, if you had Subscriber::set() like I showed, you could do:
sub get_greeting {
my ($self) = @_;
my $id = $self->{_id};
$greeting_sql->bind_columns(\my ($salut, $fname, $lname));
$greeting_sql->execute($id);
$self->set(
_salutation => $salut,
_firstname => $fname,
_lastname => $lname,
);
# magic as usual
return $self->SUPER::get_greeting;
}
If you want to hear more, I can give you more. Let me know if this has
gone over your head though. I have a system in mind that would greatly
reduce the amount of code in each of Subscriber::DB's methods that link to
Subscriber's methods.
--
Jeff "japhy" Pinyan % How can we ever be the sold short or
RPI Acacia Brother #734 % the cheated, we who for every service
http://japhy.perlmonk.org/ % have long ago been overpaid?
http://www.perlmonks.org/ % -- Meister Eckhart
--
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
<http://learn.perl.org/> <http://learn.perl.org/first-response>