Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

gnat (29)

gnat
  (email not shown publicly)

Journal of gnat (29)

Saturday May 26, 2001
01:53 PM

Easiest CGI Program I Ever Wrote

[ #214 ]
I used to write CGI stuff for a living. Online regional newspapers, local real estate agents, ISP password changing, those kinds of things. I wrote quite a few that were interfaces to databases (of newspaper articles, of properties for sale, of users and their disk quota, etc.).

It was fun at first, when I was working out how to do it, but eventually the novelty wore off and it became really boring. I developed a system that served me pretty well, but it was tedious work to develop a new application. Hardly any of it was written in a way that I could reuse. I'd developed a design I could reuse, but not really much code. And even then, it was a pain in the ass to tediously rewrite the same old crap again and again with only the fields changing.

After a break of far too many years, I just wrote another CGI program. I'm an editor for O'Reilly and Associates (send me your book proposals!), and I have about ten books in the works. I'm also incredibly forgetful (as the poor guy who had to remind me TWICE over the space of THREE EMAIL MESSAGES that we'd met at TPC4). I can't keep all the information about those books in my head (which chapters are in? do we have a tagline for the cover? do I have all the information I need to issue a contract?). Hence a database with a web front end.

This time, though, instead of writing my usual type of CGI application, I started by thinking about this 3-tier mumbo jumbo I keep hearing about from the Java folks. I hate hearing all those buzzwords, but I finally got down to the guts of it: this kind of program has three levels: a database, the objects you're working with, and the user interface. My programs in the past had jumbled all these layers willy-nilly, which is probably one reason why they were ugly and hard to duplicate.

So this time I started by writing the object class that would represent the book. A book has a bunch of attributes that I'll be getting and setting (title, author, number of chapters, etc.). I didn't use an SQL database, I maintained a DB_File index of books, and used a DB_File for each book. It's so 90s, but that's just me.

I didn't do such a good job of designing the first draft of this one, because the one class dealt with not only books but also the index of the books. I did do some things right: the attributes list is kept in the module, and I provided methods to find out the complete list of attributes, which are available, and which are taken. Also, I chose to implement a book object as a hash containing only its ID and a database handle (tied hash). The alternative was to read the database into a real hash, and then worry about updating the database manually for each change, which is so ugly that now I come to describe it I wonder how I even considered it.

So anyway, I just happened onto the sweet spot of the module design. I wrote a Tk front end (stalled because I'm not sure how to update the list of attributes and values when the user selects another book to view), and then a CGI front end. In the writing of those, I found I was missing one or two methods (mostly relating to the title database, not the book database) and that lead me to this insight:

A sign that you wrote the underlying module well is when you don't need to revisit its interface to build the next layer up.

As I refine the book application, I'm going to try to work out what made the book module work so well. This is the first time I've had fun writing one of these stupid programs since 1998. It feels good that it seems like I'm finally getting it right.

--Nat