Stuff with the Perl Foundation. A couple of patches in the Perl core. A few CPAN modules. That about sums it up.
Here's a typical bit of "controller" logic:
sub add_product_to_order {
my ( $dbh, $p_id, $o_id ) = @_;
unless ( $o_id && $o_id =~/^\d+$/ ) {
dienice("Bad order number $o_id");
}
my $o_sql = 'SELECT * FROM orders WHERE id = ?';
my $p_sql = 'SELECT * FROM products WHERE id = ?';
my $order = $dbh->selectrow_hashref($o_sql, {}, $o_id);
my $product = $dbh->selectrow_hashref($p_sql, {}, $p_id);
# snip
my $html = <<'END_HTML';
<html>
<head>...
}
That's crap. It's all crap. But that's what's usually out there. Here's a better version.
sub add_product_to_order {
my ( $self, $o_id, $p_id ) = @_;
my $order = Order->new($o_id) or $self->add_error(Order->error);
my $product = Product->new($p_id) or $self->add_error(Product->error);
$self->handle_errors; # doesn't return if errors
$order->add_to_basket($product);
$self->show_basket($order);
}
That still has some problems, but it's much cleaner, the model and view logic is more clearly separated and it's easier to read. This should be more of your end goal. Stop writing crap like the first example!
Step 1: Use MVC (Score:2)
I'm a big fan of CGI::Application, where you write subclasses that are Controllers. Within that subclass, you write subs that handle states of the webapp and yeah, when you first pick it up, you find yourself putting HTML and SQL code i
Re: (Score:2)
That's another reason why I rather like Catalyst and Jifty -- cleaner separation of concerns. While CGI::Application doesn't do as much heavy lifting, it still seems like a much better idea that what most folks do. Plus, if you can at least remember to keep the three logic types in their appropriate layers, you make refactoring much easier because of the looser coupling.
And years ago, I wrote code like my first example, too. In fact, I remember when chromatic came and worked at the same company I did a
Re: (Score:1)
Any deployed codebase used by actual customers and funded by people who won't put up with infinite deadlines has some technical debt. Your code wasn't the problem. (At least, I can't remember ever having to fix a bug in code you'd written.)