Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

RFC CGI.pm refactoring

by tachyon (Chancellor)
on Feb 14, 2002 at 12:31 UTC ( #145432=perlmeditation: print w/ replies, xml ) Need Help??

CGI.pm is the Perl standard for CGI parameter parsing. A number of criticisms are regularly aired about this module ranging from its large size, 'eclectic' internal structure and arbitrary inclusion of HTML generation which is not used or favoured by a significant percentage of users.

Its strengths include an excellent interface, extensive documentation and its extended real world testing.

Even the author suggests that this module has become monolithic and convoluted. So - time for a refactoring...

CGI::Simple provides a relatively lightweight drop in replacement for CGI.pm at about 1/3 the total size with less than half the default code load. It shares an identical OO interface to CGI.pm for parameter parsing, file upload, cookie handling and header generation. It does not provide any methods to generate HTML. The module is strict and warnings compliant, uses Selfloader to load rarely used methods on demand, and is entirely object oriented. A complete functional interface is available by using the CGI::Simple::Standard wrapper module. An extensive test suite is included. CGI.pm methods have changed somewhat across the versions. Concordance testing appears perfect against CGI.pm 2.78.

Before cluttering up CPAN with yet another CGI parameter parsing module I would be interested in what the monks think. You can get the .tar.gz here. For more details see the pod.

cheers

tachyon

s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Comment on RFC CGI.pm refactoring
Re: RFC CGI.pm refactoring
by Masem (Monsignor) on Feb 14, 2002 at 12:50 UTC
    I thought that this was what CGI3.pm was to take care of; even from Lincoln Stein's homepage he states that CGI3 is a modular design with some performance improvements. Unfortunately, nothing's been done with it since 2000, so I don't know what the status of it is.

    -----------------------------------------------------
    Dr. Michael K. Neylon - mneylon-pm@masemware.com || "You've left the lens cap of your mind on again, Pinky" - The Brain
    "I can see my house from here!"
    It's not what you know, but knowing how to find it if you don't know that's important

      Hmm....it seems like that's CGI.pm version 3.0 or the latest version of CGI.pm. He's a busy guy working on lots of stuff in biology (he's a member of the bioperl project) so his focus is probably not immediately on CGI or perhaps he's working on a new version. It seems like version 3 is the work of someone else.

      metadoktor

      "The doktor is in."

Re: RFC CGI.pm refactoring
by mirod (Canon) on Feb 14, 2002 at 17:07 UTC

    Frankly I don't see the point: CGI.pm's main asset is that it works, it is used all over the web and is extremely robust.

    Now maybe it is convoluted inside, and it does 2 things instead of one. But it is also very cleverly written and performances don't suffer from the slight feature bloat. In any case if you want performaces you can use mod_perl, I would think that starting a Perl interpreter is what takes up time, not loading CGI.pm.

    So I for one am willing to take CGI.pm as a black box, size and all, and even to use the HTML generation methods for quick forms that do not justify using a templating system.

    Using a smaller module does not IMHO justify the security (and stability) risk involved in using a new module.

Re: RFC CGI.pm refactoring
by perrin (Chancellor) on Feb 14, 2002 at 17:10 UTC
    There are 3 or 4 other modules on CPAN in the CGI namespace that already do this. Take a look around before you upload yours.
Re: RFC CGI.pm refactoring
by Dog and Pony (Priest) on Feb 14, 2002 at 18:06 UTC
    Interesting. If nothing else, because I was pondering whether to do this exact same thing, and even more interesting, I was also gonna use the name CGI::Simple. :)

    I use CGI.pm all the time, but I only use a very minor portion of the module, more specifically it is usually the header method, parameter parsing and redirects. Sometimes, some other minor stuff too, but that is about it. So why should I pull in the whole of CGI.pm, especially when web programming should be as fast as possible? Yes, I know about mod_perl and all that, but sometimes that is not possible, and sometimes it is not worth the effort - doesn't mean you shouldn't optimize when you can.

    Do upload it. I for one will use it. Thanks for the effort. I appreciate it. :)

      I use CGI.pm all the time, but I only use a very minor portion of the module (...) So why should I pull in the whole of CGI.pm, especially when web programming should be as fast as possible?

      I use Perl all the time but I only use a very minor portion of the language... you get the idea ;--)

      Basically the extra functionality comes for free. Have you looked at the code of CGI.pm? Unless you use a method it is never loaded. It uses tons of clever tricks, its own version of Exporter (saving you 300 lines), and under 700 lines of "real" code, the rest being loaded on demand.

      Are there any benchmarks of CGI::Simple against CGI?

        Yes there are. The test suite contains just under 1000 unit tests. This includes the entire CGI.pm CGI related test suite plus just under 100 concordance tests that have the basic form:

        use CGI; use CGI::Simple; use Test; # make a CGI environment; $ENV{'BLAH'} = .... [snip] my $qc = new CGI; my $qs = new CGI::Simple; my @params = qw(blah blah); my $qc_scalar = $qc->some_method(@params); my $qs_scalar = $qs->some_method(@params);; my @qc_array = $qc->some_method(@params);; my @qs_array = $qs->some_method(@params);; ok( $qs_scalar, $qc_scalar ); ok( join'',@qs_array, join'',@qc_array ) # continues for all common methods

        Concordance with CGI.pm 2.78 is 100%. CGI::Simple loads under 300 lines by default and uses Selfloader. As it is inherently OO it does not use Exporter at all and is considerably faster than CGI.pm when called OO. The wrapper module that gives you a functional interface CGI::Standard uses a couple dozen lines of code to make the namspace exports either on demand (using an AUTOLOAD routine) or as single methods or method sets.

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

        As requested by /msg from mirod on Benchmarking CGI::Simple is just under 3 times faster performing the most common function - getting the value of a param. It is variably faster on other common operations. Load times are more difficult to evaluate accurately. I would be interested in what you find.

        use Benchmark; use CGI; use CGI::Simple; $ENV{'QUERY_STRING'} = 'foo=bar&baz=boo'; $q = new CGI; $s = new CGI::Simple; timethese(250000, {'CGI' =>'$q->param("baz")', 'Simple' => '$s->param( +"baz")'}); __DATA__ Benchmark: timing 250000 iterations of CGI, Simple... CGI: 27 wallclock secs (27.19 usr + 0.00 sys = 27.19 CPU) @ 91 +94.56/s (n=250000) Simple: 10 wallclock secs ( 9.99 usr + 0.00 sys = 9.99 CPU) @ 25 +025.03/s (n=250000)

        Update

        For a more in depth analysis see CGI::Simple vs CGI.pm - Is twice as fast good enough?

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: RFC CGI.pm refactoring
by Amoe (Friar) on Feb 14, 2002 at 18:43 UTC

    In principle, I think CGI::Simple is a good idea; I don't think that the module CGI is cluttered by unnecessary functions (I've used most of it, and it was all necessary), but I'll go blind if I read the source. I'm not sure about its performance issues, having always worked with it - I expect raw HTML generation would be faster.

    But if CGI::Simple takes out the HTML generation methods, I won't be switching. I really hate embedding HTML; the Camel's claim that perl "makes different things look different" is all very well, but embedding HTML makes code so ugly. I think CGI.pm's interface has such a distinctive style that it would obscure the code to manually generate HTML. Oh, and where's the data on the methods not being used by "a significant percentage of users"? Most scripts I've seen use them.



    --
    my one true love

      Naturally it depends on where you work but round here, and in many other places, graphic designers generate virtually all the HTML. Templating allows coders to code perl and designers to design HTML. This way there is essentially NO HTML in your perl code be it in the form of HERDOCS or CGI.pm HTML generating stuff.

      IMHO Perl coders fall into two categories, split roughly 50:50. One half hate the HTML side of CGI.pm and half love it. No prizes for guessing which side I fall into.

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Re: RFC CGI.pm refactoring
by little (Curate) on Feb 14, 2002 at 21:16 UTC

    I think the discussion goes to a wrong direction.

    Wait! I'd like to say why I think so before you kill me. :-)

    The documentation for the Common Gateway Interface does not mention the ability of producing a specified _document_ syntax or structure upon browser requests but how to handle browser requests and how to reply to them by giving declarations _about_ the document to be returned, not about its specific content.

    Therefore the question is, how all these nice and very usefullfull HTML and now xhtml spitting out functions made it into a module called CGI.pm. Well, I like the way it is, but I dislike the idea of seeing CGI.pm updated twice or thrice a year because of new document syntax, which is not troubling the CGI as an interface at all, except additional mime-types to be declared, well.

    To get to the point: _I think_ all functions and methods that do not belong _by definition of the interface_ into CGI.pm should be "deported" to another modul or should be replaced by another modul as there are now plenty of them.

    To keep compatibility with older versions, upon 'use CGI;' an additional option might be passed, for example 'use CGI(-noTags);' indicating that I want the plain interface communication handled by CGI.pm and nothing more. If that option is omitted CGI.pm should load all that baggage and overload it is carrying then in other modules as CGI::HTML or CGI::SGML or CGI::XML, which shows that there are already enough modules out there to be a replacement or inplacement for the one or the other.

    I just, and this is the main reason why I write this, don't get the idea of having a module named CGI::Simple, even if it is not implementing a simpler version of the CGI but just all of it and having a module called CGI which contains more than its name should allow.

    Ok, now you can tell me why you thought you could kill me upon having read the first sentence, if that ever was the case :-)


    Have a nice day
    All decision is left to your taste
    Update15.02.2002 12.15 CET
    I just had a closer look again at CGI.pm's POD and I think it was 'use CGI qw/:cgi /;' which was (still is?) supposed to fullfill that. So there would by now not even be a need for "-noTags" or the like.
    Which does not change my opinion to better move the "baggage and overload" out of the core CGI.pm to other modules in the CGI:: namespace or link them to other modules.

      Excellent point: ++.

      CGI.pm is definitely been better than what most new programmers could write on the first try. But by the same token, it would be easier for most people to write their own CGI handler, MIME parser, browser isolation layer, and formatting system than to figure out CGI.pm.

      My own objection to CGI.pm is the interface itself. Interfaces are protocols, and ideally, a library interface should be easier to learn and use than the thing it abstracts. I'd personally argue that CGI.pm's interface is both harder to learn and less flexible than the CGI per se.

      It didn't start that way, but bloat is part of the natural software lifecycle. When something gets so big and unwieldy that people would rather reimplement it than learn the existing version, it's time to clean house. The new versions aren't waste, they're competition, and competition is a Good Thing.

        CGI.pm is definitely been better than what most new programmers could write on the first try.

        Now, that's an understatement.

        But by the same token, it would be easier for most people to write their own CGI handler,

        Crap.

        MIME parser,

        Even more crap,

        browser isolation layer,

        still more crap,

        and formatting system

        We're reaching the limit of the sewage system here, folks.

        than to figure out CGI.pm.

        This (one of the worst posts I have seen on Perlmonks (--) rehashes all the arguments put out by stubborn newbies who for some reason nobody can fathom insist on reinventing the wheel every time instead of using good code written by someone else. Witness all those people who refuse to use File::Find and File::Copy. Why, why, why, why?

        Sorry about the rant and the strong language but this is a pet peeve of mine. I feel I made no progress in learning Perl until I started to use its features and modules rather than try to use it as some sort of complex version of C.

        Regards,
        Helgi Briem

(Ovid - let's look at this again) Re: RFC CGI.pm refactoring
by Ovid (Cardinal) on Feb 15, 2002 at 22:06 UTC

    I'm reading through a lot of these posts and I'm a little disheartened. Let's face it, tachyon isn't exactly coming to us with a 10 line CGI parsing routine and saying "should I upload to CPAN?". He asked for some feedback and in my mind, that translates to a code review, but many appear to object without reviewing the code! There was some limited support for this, but again, without apparently reviewing the code.

    CGI.pm is a wonderful "don't leave /home without it" sort of module. However, it does have some significant issues that warrant competition. CGI::Lite seems to be well-regarded as is Apache::Request. Is that it, though? Is this all that we allow in the club? CGI::Simple seems to be a promising way of overcoming many of the typical "I won't use CGI.pm" objections.

    A while ago, tachyon and I were talking about this and I reviewed his code. While I made a couple of suggestions, for the most part, I liked what I saw. What really impresses me about this effort is that, with just under 1000 unit tests (going by what tachyon said), he states that this module passes 100% of the tests. Note that these include all of the CGI.pm tests. So, if the test suite is complete, we have 100% backwards compatibility with a lightweight, well-written module. I think that's something to consider.

    Yeah, we can say that "CGI.pm" works, don't use anything else, but what does that get us? Stagnation. Let's try new things. Let's experiment. Even if this code offered no advantages other than much cleaner internals, it should be worth considering on that basis alone, not just dismissed out of hand, as some here seem to have done.

    This isn't to say that we all need to rush forward and embrace what tachyon has done, but I think we should give it more consideration that what has been done here. Let's look at the features:

    • 100% backwards compatible to CGI.pm for the functions it chooses to implement.
    • strict and warnings compliant.
    • Faster during runtime (this, of course, would be a spurious benefit if it didn't live up to its other claims).
    • Possibly faster compilation time (useful in a straight CGI environment).

    Now, if you have to have those HTML generating functions, don't use CGI::Simple. Frankly, I use those HTML generating functions if I'm doing something really, really minor. Otherwise, though, I use templates. If I use templates, CGI::Simple perfectly fits my needs. If this gets to the CPAN, I'm really going to give this module some serious consideration.

    Cheers,
    Ovid

    Join the Perlmonks Setiathome Group or just click on the the link and check out our stats.

      Thanks for your post Ovid As it happens I have posted the relevant benchmarks at CGI::Simple vs CGI.pm - Is twice as fast good enough? The title is self explanatory but the actual results are interesting. You may not have realised how much of a performance penalty use strict; applies for instance.

      cheers

      tachyon

      s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

        Read about module the bugs. These bugs should be fixed:
        http://rt.cpan.org/Public/Dist/Display.html?Name=Cgi-Simple

        Best regards,
        Webmaster33
Re: RFC CGI.pm refactoring
by Anonymous Monk on Feb 10, 2007 at 05:15 UTC
    Hi, found out about CGI::Simple today. I know, 5 years too late, but I was wondering about the name "Simple" which indicates some interface simplification while actually it is a simplification in implementation. I would have voted for the name "CGI::v2" or "CGI2" or something like that. Well, just an itch. Keep up the good work.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://145432]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (16)
As of 2014-07-10 17:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    When choosing user names for websites, I prefer to use:








    Results (213 votes), past polls