Instead of declaring those subs statically, you could generate the subs dynamically based on the content of the table.
BEGIN {
my $dbh = DBI->connect(...) or die DBI->errstr;
my $sth = $dbh->prepare(
qq(
SELECT
price_type_id,
price_type_label
FROM
price_type
)
) or die $dbh->errstr;
$sth->execute or die $sth->errstr;
my $data = $sth->fetchall_arrayref or die $sth->errstr;
for my $row (@$data) {
my ($id, $label) = @{$row};
my $name = lc($label);
$name =~ s/\s/_/;
eval qq(
sub $name {
return shift->get_price($id);
}
);
}
}
Though, I'm sure there's a cleaner way. One could, for example, make the price_type_label the argument to get_price, and resolve the price_type_label to the price_type_id within get_price. This solution provides for the three distinct subroutines for the different price types.
I'd say this only provides a solution to the part of the problem where the data is hardcoded. The presentation layer still needs to discover which methods will be available to it. Arguably, this could be done using the same table. That doesn't feel particularly clean to me, however.
minor update: s/tr/s/
minor update2:
s/$_\[0\]/shift/
--
jwest
-><- -><- -><- -><- -><-
All things are Perfect
To every last Flaw
And bound in accord
With Eris's Law
- HBT; The Book of Advice, 1:7