Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

use CGI and die;

by hardburn (Abbot)
on Jun 10, 2003 at 14:59 UTC ( [id://264700]=perlmeditation: print w/replies, xml ) Need Help??

Ovid's use CGI or die; is something of a classic around the Monastery. At the time it was written (more than two years ago), I'm sure it was good advice. Indeed, CGI.pm is far superior to cgi-lib.pl, and definatly better than doing parameter parsing by hand. Certainly, you could be doing far worse than to use CGI.pm.

However, I wonder if it is really a good idea to recommend this module anymore. Arguments against CGI.pm are as follows:

  1. The internals are a mess
  2. The documentation reads more like a tutorial than a man page
  3. It should only be used for basic CGI tasks, such as parsing params and handling cookies. HTML generation is right out.
  4. There are much leaner, meaner alternatives on CPAN.

I'll take these arguments in the order above.

1. The internals are a mess. For starters, look through the CGI.pm code. Search for 'strict'. I did this on CGI.pm version 2.752, and all I got were a few comments. This module would take a major effort to get working under use strict. Few people would suggest using a more recent module that couldn't run under strict.

2. The documentation reads more like a tutorial than a man page. The root-level POD document for any module is inevitably going to be the most referanced documentation on that module. It should thus be written to be used as a continuing referance for people who are already familer with the module--in other words, a man page. Tutorials have their place, but that place isn't at the main module document. Doing so just makes unnecessary digging for people who want to know the specifics of how a certain subroutine works.

3. It should only be used for basic CGI tasks. This is a matter of debate, and there are many promanent Perl programmers on both sides of the issue. The argument is that all those HTML-generation subroutines in CGI.pm just shouldn't be there. Plus, they are contributing to the documentation problems mentioned in #2. Perhaps it is better than printing them by hand, but wouldn't it be even better to use a templating system?

Perhaps a templating system is overkill for a quick-and-dirty CGI, in which case we are back to either generating HTML by hand or using a module to do it for us. Even if this is the case, those subroutines still don't belong in CGI.pm. Other module exist with similar functionality (see below).

If CGI.pm were reduced to param() and maybe cookie(), most people wouldn't notice the difference.

4. Other modules exist with similar functionality. This in itself isn't a reason to dump it or any other module, but if the community were to decide to move away from CGI.pm, it is important that alternatives exist. A short list:

  • CGI::Lite -- All you need for parsing basic input parameters
  • Apache::Request -- Interface is the way I think CGI.pm should have been in the first place. Claims that param() method is faster than Apache's native Apache->args. Only works under mod_perl.
  • HTML::Stream -- I'm not a fan of these quick-and-dirty HTML generation modules, but if you're into that sort of thing, here you are.
  • HTML::LoL -- Another quick-and-dirty HTML generation module.
  • HTML::EasyTags -- And another one, this one very similar to what is currently in CGI.pm.

This is certainly not an complete list. CPAN is way too big for it to be. This just lists a few of the alternatives.

Overally, I think that CGI.pm's time has passed. It is likely to be used for quite a while longer, at least until another CGI param-parsing module makes it into the core--perhaps not even then (we're still working on getting rid of Perl4 code, after all). Even so, I think it's time to recommend alternatives where it is possible to do so.

Update: Slight problem in last paragraph fixed (orginal left out "another" in second sentance WRT CGI param-parsing module).

----
I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
-- Schemer

Note: All code is untested, unless otherwise stated

Replies are listed 'Best First'.
Re: use CGI and die;
by Ovid (Cardinal) on Jun 10, 2003 at 15:09 UTC

    Regarding whether or not messy internals are a reason not to use something, if I may be so bold as to suggest that Perl 5's internals are a bit of a mess. That's part of the impetus behind Perl 6, but Perl 5 works and I'm not going to stop using it :) You also might find the following thread on that subject of interest: Paradigm Shift - Don't use strict.

    If you're going to suggest alternatives, don't forget CGI::Simple by tachyon. It's an excellent module and, more importantly, it's a drop-in replacement for CGI.pm. It seems to meet the requirements you specify and it since it's a drop-in replacement, it has an interface that most CGI programmers are already familiar with. In fact, I might even vote it "most overlooked module".

    Cheers,
    Ovid

    New address of my CGI Course.
    Silence is Evil (feel free to copy and distribute widely - note copyright text)

Re: use CGI and die;
by chromatic (Archbishop) on Jun 10, 2003 at 17:13 UTC

    Let me play biologist's advocate for a moment.

    The internals are a mess.

    How often do you need to look in a module's internals? Have you read strict or Carp lately?

    The documentation reads more like a tutorial than a man page.

    Again, I don't see the problem. It has tremendous sample code, and I've found just about everything I've ever needed in there. Maybe having a very short man page would help, but I make liberal use of the search command in my pager.

    There's a lot of stuff that could be *pruned* from the documentation, but that's just my opinion.

    It should only be used for basic CGI tasks.

    I don't particularly ever want to write another form field stickiness loop again. I don't care for most of the HTML generation, but they're convenient in spots. This is a matter of inertia and taste, and I don't think those make for strong arguments either way.

    Other modules exist with similar functionality.

    The same could be said about the other modules!

    CGI is installed by default on any version of Perl worth using. It works. (It even does P3P cookies.) It's well tested. It has copious documentation. Just about anyone worth listening to about web programming in Perl knows how to use it.

    That's a lot to overcome. Granted, I do use CGI::Simple in Jellybean 0.30, with a blessed glob patch, but that was a conscious decision. I still recommend people start with CGI.pm.

Re: use CGI and die;
by diotalevi (Canon) on Jun 10, 2003 at 16:52 UTC

    You forgot to mention the sticky form values. It is immensely useful to be able to insert a form element into a template and have it just work correctly without lots of template-side gyrations. In fact, I'd say this is the proper way to use things like CGI::Application and HTML::Template.

    sub fizzbinbox { my $self = shift; my $tmpl = $self->load_tmpl; my $q = $self->query; $tmpl->param( fizzbin => $q->checkbox_group( -name => 'words', -values=>['eenie','meenie','minie','moe'], -defaults=>['eenie','minie']) ); return \ $tmpl -> output; }
      I'll upvote you and reply here. If you have *ever*, ever, ever found yourself writing something like:

      if ($query->param('foo') eq "bar") { do this } elsif ($query->param('foo') eq "mynameisdave") { do something completly stupid } else { ...

      Then *STOP* now and start using CGI::Application. It's the best thing since nutella on that thick bread your mum used to make and should be used at all times for any CGI application that used multiple form, pages, or any other kind of multiple foo application.

      Try it, then slate me for saying it if you don't like it. But you like that nutella, so come on, I must be right, right?

      Over and out.

      - wil
Re: use CGI and die;
by mirod (Canon) on Jun 10, 2003 at 18:18 UTC

    OK, I'll bite too:

    1. The internals are a mess

    Do you have any idea WHY the internals are "messy"? CGI.pm is arguably the most important Perl module ever. It ships with the core and is used by tens, maybe thousands of users. Which means that it is worth optimizing. To Death. Licoln spent lots of time and effort making it as fast as possible. For you and I it means that CGI.pm is fast. For him it means bearing the cost of a harder-to-maintain module, in which he threw away a lot of the rules that let you write clean code. So be happy he was ready to do this and accept the fact that non-premature optimization leads to non-trivial code.

    3. It should only be used for basic CGI tasks, such as parsing params and handling cookies. HTML generation is right out.

    This is true for most "serious" projects where you have the time to write proper templates, but believe me, for lots of "quick hacks" the fact that the parameter parsing and the HTML generation are integrated is pretty useful. It lets you write quickly a debug interface to a DB, or a Web interface to a command line tools.

    So you are of course entitled to use an other module for your CGI tasks, but please do not think that CGI.pm is not useful and that "it's time has passed". It is still the best module people who start doing CGI can use.

      As fast as possible? I don't think that was a design goal for CGI.pm. The alternatives mentioned here are generally faster.

      CGI.pm is a mess because it does too much and hasn't had a good refactoring. Lincoln himself has said as much in the intro to his book, among other places.

      I agree with all of these comments: CGI itself is slow, CGI.pm probably lacks from an initial design that tried to cram too much features in a single module, and it is possible to write a much faster module by leaving out the HTML generation parts of CGI.pm. This does not detract from my initial point though: sometimes during the life of the module (I would guess around version 2.0, it's hard to tell from the Changes file) Lincoln started optimizing it, which lead to the current code. In short the code is not hairy because the author can't code properly, it is hairy because the author knows what he is doing and he does hairy things in order to provide its large user-base with as much speed as possible, while staying backward compatible with older versions (how's that for short! ;--).

      I would add that an other reason to use a module is the support it gets from its author. In this case it has been really good, just look at the Changes list. I really appreciate the fact that CGI.pm generate conformant XHTML for example.

      Which means that it is worth optimizing. To Death.

      I have a hard time swallowing that. In a regular CGI, the start-up time to fork off a new interpreter and load your program is going to be the limiting factor for almost any CGI out there. You would have to be running massive numbers of input params before that becomes the limiting factor.

      If you're running mod_perl, things are different. But in that case, Apache::Request claims to be faster (I haven't looked at the actual benchmarks, so I'll take their word for it for the moment).

      ----
      I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
      -- Schemer

      Note: All code is untested, unless otherwise stated

Re: use CGI and die;
by shotgunefx (Parson) on Jun 10, 2003 at 17:58 UTC
    I'll have to agree with most of the responses here.

    While most of my work starts off with "use strict; use warnings;" I have, no problem discarding them when it makes sense. Many times, most of the benefit from these are when you're developing anyway. There's nothing wrong with not using them when you know why you are not and what the implications are.

    While the HTML functionality of CGI, should have been a subclass, it isn't, but it works and you get a CGI swiss army knife in core which is not a bad thing at all. Now if you wanted to argue about adding a lighter alternative in core, I would think that would be a good idea.

    -Lee

    "To be civilized is to deny one's nature."

      I have, no problem discarding them when it makes sense.

      Nor do I. Bug CGI.pm doesn't use them at all, mostly because of legacy code. For similar legacy reasons, subclassing CGI.pm is a nightmare (see the link Ovid posted above), so that isn't a practical alternative to the HTML subroutines.

      And yes, I would very much like to see lighter alternative (like CGI::Lite) in the core. The parent node's title to the contrary (that was just a cute pun on a well-known node), I don't think CGI.pm is so awful that it should go the way of symbolic refs. Rather, I think it's funcationality has been surpassed by alternatives.

      ----
      I wanted to explore how Perl's closures can be manipulated, and ended up creating an object system by accident.
      -- Schemer

      Note: All code is untested, unless otherwise stated

        While it is not pretty, I've subclassed it many times and while I wouldn't quite describe it as a nightmare, it's certainly not simple.

        I got the title reference, hard to miss in this place. It's one of the few things that irk me here. "This or DIE" and "BLAH considered harmful", I think it's almost all good when used appropriately.

        -Lee

        "To be civilized is to deny one's nature."
Re: use CGI and die;
by Joost (Canon) on Jun 11, 2003 at 09:18 UTC
    I agree to most of this post, but I would like to point out this passage in the README of CGI::Lite which makes me reluctant to use it in any real code:

    Note from the CPAN administration: The CGI::Lite module seems to be abandoned by its original author. We cannot contact him anymore. The 2.0 release has been made on 2000-08-20. This 2.001 release is just an emergency release that fixes the most urgent security need. It is not endorsed by the original author. It was put together by me after the advisory http://msgs.securepoint.com/cgi-bin/get/bugtraq0302/94.html on the bugtraq mailing list. Thanks to Ronald F. Guilmette for bringing up this issue.

    I do not and will not maintain CGI::Lite and would welcome volunteers to take it over.

    2002-02-17
    andreas koenig

    Joost

Re: use CGI and die;
by adrianh (Chancellor) on Jun 11, 2003 at 13:41 UTC

    I'm going to carry on using CGI (when appropriate) for several reasons:

    • It works.
    • It's actively maintained.
    • It's a core module.
    • Despite being a huge fan of Template sometimes I just want to print out some HTML for a quick hack. TMTOWTDI and all that.

    The documentation style isn't what I prefer, but I have heard as much praise as criticism for it - so I'll put it down to personal taste.

    While it's not the fastest thing on the planet that doesn't cause me problems. In my experience you move to a mod_perl environment long before the performance/size issues of the module become an issue.

    While I have nothing against the various other modules you mentioned none of them give me enough extra utility to think about moving - or recommending others move.

Re: use CGI and die;
by nite_man (Deacon) on Jun 12, 2003 at 07:52 UTC

    In my mind, using Embperl or Mason with mod_perl is better choise than using CGI for development of big web applications.

    Of course, some CGI scripts which do some administration tasks will be alive during long time. But for commercial web application or user web interface will be better to use Embperl or Mason with mod_perl.

    Although those tools need additional effort for installing and configuring, they leave to power features for web developerment and possibility to build an application with clear and flexible structure. A control of sessions, caching, database and file system interface, mime types control etc are implemented in those tools. It releases of development of routine things and leaves to concentrate on your application.

    Of course, both CGI and mod_perl with Embperl or Mason are entitled to existence. One must not to say 'Well, CGI is deprecated, all have to use mod_perl with Mason or Embperl!'. It's not correct. We should choose a technology according to our goals and tasks.

    --------------------------------
    SV* sv_bless(SV* sv, HV* stash);
    

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://264700]
Approved by l2kashe
Front-paged by abell
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others exploiting the Monastery: (7)
As of 2024-04-19 16:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found