A Fond Farewell to CGI.pm

This text is adapted from a lightning talk delivered at YAPC::NA in Austin, TX on June 4, 2013.

Alas poor CGI.pm. I knew him, Horatio.

OK, I admit it: I’ve bashed CGI.pm plenty of times. It’s slower than alternatives (who remembers CGI::Lite?), the HTML generation looks like a terrible idea in retrospect, and the liberal use of globals in the code is pretty ugly. I wouldn’t tell anyone to use it now, and I’m not here to argue against removing it from the Perl core.

But... most of the people in this room are probably here in one way or another because of Lincoln Stein and CGI.pm.

I first encountered CGI.pm back in 1996 when I was working at CitySearch.com. There was a guy in the office (Eric Hammond, now known for his work with EC2) who knew Perl and was doing amazing things with it, like writing a WYSIWYG HTML editor with exact positioning using generated tables. He got me going on CGI.pm and DBI and it was amazing! Lincoln had replaced the older Perl 4 cgi-lib.pl with a full-featured Perl 5 module that had lots of bells and whistles.

It’s hard to appreciate now what a big deal that was for Perl. Everyone suddenly wanted to put things on the web, and Perl had a fast and easy way to do it. Perl got a whole new user base out of that, and became closely linked with web development. You want to do something on the web? Better learn Perl.

And to help you learn, CGI.pm had fantastic documentation. The documentation was actually so comprehensive that it was published as a book, Official Guide to Programming with CGI.pm by Lincoln Stein, subtitle "The Standard for Building Web Scripts." And it’s true, this was actually the best guide to CGI programming in any language that existed at the time.

But beyond the historical significance, take a look at some of the things that CGI.pm introduced us to:

  • CGI::Carp captured errors and printed them right to the browser. You didn’t have to switch to your terminal and look at the error log. Huge timesaver.
  • You could test your script by passing parameters on the command line. You could even write script that worked when called via command line or CGI. So cool!
  • It had easy handling of cookies, which were still new at the time.

Later, when Doug MacEachern came along with mod_perl, CGI.pm was adapted to allow running under mod_perl with no modifications. (Or, with a ton of modifications if you were naughty and didn’t use proper scoping.) With a few additional lines, you could run the same code under FastCGI too. CGI.pm was the first web environment abstraction layer in Perl.

The other thing about CGI.pm was the code. Oh, I know, it has some ugly. It has an OO interface but it keeps state in globals instead of in the passed object. If someone wrote code like this on a project I was responsible for, I would be sad. But when I was a Perl newbie, looking at the CGI.pm code really opened my eyes to the incredible things you can do with Perl. It generates both a procedural and an OO interface using AUTOLOAD, eval, and a pile of strings. It detects the environment and adapts. It really takes advantage of the metaprogramming capabilities of perl.

So, now it may be time for CGI.pm to leave this Perl core. There are other ways to do this work now, and they're better. Let’s pause for a moment to give thanks, for all that it’s done for us. Like Bilbo and Frodo, it will set sail for the elven lands. Rest well, old friend.


A lot of people don't seem to realize that CGI.pm replaced a bunch of awful hand-coded solutions. The HTML bits were unnecessary, but parsing CGI params sensibly added a bit of sanity to the early web.

What, you're not going to remove your shirt?

Leave a comment

About Perrin Harkins

user-pic I blog about Perl.