This page expresses opinions I had over ten years ago. I don't think I still hold those opinions, for various reasons that are probably no longer important, primarily because nobody in their right mind writes CGI any more anyways. But here's the crux of it - using mature, well-tested modules is always better than rolling your own. I was wrong. Lincoln was right. But I'm going to leave this here for historical reference anyway, and as a reminder, to myself, of how full of myself I was just a few short years ago.

Why I don't use CGI.pm

Lincoln Stein has put together an impressive set of tools, called CGI.pm, for use in writing CGI programs in Perl. They have become widely accepted as THE way to do things, and there are some folks that think that you are not really a real Perl programmer, whatever that means, if you do not start every Perl CGI program with the magic incantation "use CGI;".

I have long been a dissident, persisting in using other methods of doing things. This is not merely because I am stubborn. I have some reasons that I have thought a lot about. And I will probably keep doing things this way, at least as long as I have customers that are happy with the way that I do things.

So, why do I do things this way? OK, here's my position and my reasons.

I believe that the code and the UI should be kept separate as much as possible. This is mostly for practical reasons, but also has to do with the beauty of the code.

Practical reasons: I have customers. My customers do not know Perl. Frankly, that's fine with me, because if they did, they would not be my customers. They do, however, know HTML. I am not good at web site design. Just look at my web site some time, and you will agree with me. So I write Perl code, and leave the HTML page design to my customers. This implies that the two are not the same thing, and I don't have to know one to do the other. To this end, I have developed my own method of putting HTML in HTML template files, and the code in Perl files, and never the twain shall meet. This is of course not possible, because you have to make some of the HTML pages dynamically. I've used Text::Template - one of the venerable old CPAN modules - to make HTML template files, and fill in variables at run time. The people editing the HTML pages see some weird things in the files that don't look quite like HTML, and they leave them alone. But they don't ever have to edit Perl code in order to change how their pages look.

The traditional way (pre CGI.pm, perhaps pre cgi-lib.pl) to do this sort of thing was to have everything inline in your code.

print "<html>;\n";
print "<head><title>Page title</title></head>\n";
etcetera.
While this is ugly and confusing to the end user, they can at least see where the HTML is, and can figure out how to change it. Putting it in a "here document" (the print <<End; construct) inproves readability. But the basic problem is still there. The customer has to edit a Perl file, and look for HTML in it, in order to change their vlink color. This is icky.

Along comes CGI.pm and makes things infinitely worse, in this regard at least. Now, instead of putting in my code:

print '<INPUT TYPE="textfield" NAME="State" VALUE="gaseous" JUSTIFICATION="RIGHT">';
I now do:
   $field = $query->textfield(-name=>'State',
                              -default=>'gaseous',
                              -justification=>'RIGHT');
And somehow, that's better? Ick. By the way, that's an actual example from the CGI.pm documentation, so someone thought that this was a good idea. Now, the customer is completely unable to edit the appearance of their pages, because not only is it embeded in Perl code, it looks completely unlike HTML, and they have no idea what they would need to modify.

And so I use the Perl Text::Template module to make template files which my Perl programs fill in at run time. This means that the customer is able to edit regular HTML files, which might have a little goobledegook in them that they don't understand, but, for the most part, it's just HTML.

So, in conclusion, it would seem to me that CGI.pm is great if you are writing quick-and-dirty one-off CGI scripts that you will never have to change, and nobody but yourself will ever have to look at. However, if you ever intend to deliver a product to a customer, it is evil evil evil (there, I said it, I feel better) and will guarantee that they will not come to you for the next project. It makes them feel like an idiot, and make them think that you are making things unnecessarily complicated. ("I just wanted to change the color of the text right there. Why do I have to hire a programmer to make that change?")

I know, it was a little lengthy, but it's something that I have thought a lot about, and since this is what I do to pay my bills, it is important that I keep my customers happy.

I should say, for the record, that when I talked with him at the Perl Conference in 1998, Lincoln did discuss with me the notion of template-based CGI applications, but he was seemed rather dismissive of the idea, particularly of the idea that I had a different way of doing things, rather than using PHP, or EmbPerl, or ePerl, or one of the other existing solutions to this problem. All of those products have the downside that now, instead of the HTML being in the Perl code, the Perl code is in the HTML, and you have the same problem all over again.

One final thought, just so I'm not misinterpreted. Lincoln Stein is clearly a brilliant programmer, and clearly knows way more about Perl than I ever will. CGI.pm is also clearly a great package, when used to solve certain problems. It's great at maintaining state in HTML forms, and in various other CGI-related tasks. It just makes it very difficult for a Perl-impaired end-user to modify the look of the resulting HTML page, because all the HTML tags are now in OO calls buried in your code. So it's really a question of using the right tools for the right tasks. My task - writing CGI applications for folks to use on their intranet sites - requires a different set of tools.

Rich Bowen
<rbowen@rcbowen.com>