in reply to Perlmonk's "best pratices" in the real world

But their code still works. and it works well.

Deifine "work". There's "work" as in "it runs, and covers the general case", and then there is "its robust, and will either handle edge cases without bugs, or will at least immediately stop when it detects one". A house of cards can stand a long time, as long as you don't have any sudden gusts of air or vibrations.

As for your "must-have" list:

use CGI.pm!

It's param() and header() methods are absolutely cruicial. There are so many edge cases in handling those two things that you're a fool if you try to do it on your own. You should either use CGI.pm or one of the other modules that replicate its functionality.

It's other methods (like HTML generation) are more debatable.

use strict! use warnings!

The only time I've really needed to shut off strict is the refs portion, and only for a tight lexical block. Most of the one-liners I write don't have strict, though I often end up typing my before variable names anyway, just out of habit.

I think I've only shut off warnings once, on a CGI in production that had been otherwise been working fine for months, but was spewing warnings in the error log. Again, it was only done for a single, tight lexical scope.

use placeholders!

Absolutely necessary. I have yet to see a single reason why they shouldn't be used. They are only slightly harder then interpolating the variable directly into the statement, they're infinately safer, and they're often more efficient (since the statement can be cached).

use OO!

Necessary far less then OO-purists would have you believe. OO isn't about reducing complexity, but keeping it managable. If your application is simple, then OO isn't really helping you.

It might be that a given module uses an OO-ish interface, simply because its convient to do so (though you can only call them 'OO' in the sense that they use blessed references or are called as class methods). Though I feel some modules currently using an OO-ish interface are better served with an Exporter-style (Email::Valid comes to mind).

use templates!

Should be used more often then not.

use CGI::Application!

CGI::Application is meant to be used when you have several form pages, each one feeding data from the last. I'd say if your CGI has three or fewer pages, then don't bother with CGI::Application. YMMV.

am i alone, and simply one of few lousy, undisciplined coders, or is perlmonks (as much as i love it!) a bit too perfectionistic at times??

My observation is that Perl Monks tends to be a bit different from many of the older sections of the overall Perl community. Many of Perl Monk's users (myself included) started Perl with Perl5 and a well-developed CPAN. The consequence is that many of the coding techniques used by those who have been around since Perl4 or earlier are considered bad form.

So yes, I do think Perl Monks tends further twards the more conservitive coding standards of compsci then most of the Perl community, though it is still part of the Perl community and will always be more liberal coders then Java. I see this as more of a good balance point then being 'too perfectionistic'.

----
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: Re: Perlmonk's "best pratices" in the real world
by schweini (Friar) on Nov 13, 2003 at 16:20 UTC
    That BBX-code i mentioned works in the sense of being 'functional' - i.e. does what it's supposed to do, but impossible to expand. actually, for the last year, i've been replacing all of it with my perl-code, and this meditation was in part inspired by the fear that ina couple of years, some poor schmuck will have to look at my code the same dazzled way i've been looking at that BBX stuff.

    re: CGI.pm
    i've always used it in the 'old school' way of getting my params (via Vars()) with it, and then basically forgetting about it. i prefer using my own header-generators and HTML-printing subs.
    re: strict/warning
    i frankly tried it a couple of times, but got annoyed by the a bit over-pedantic messages makeing a big fuss about nothing too serious. but iread about 'no strict vars' somewhere, so i'll give that a shot...
    re: placeholders
    i've actually been advocating placeholders on the DBI-list and here (i think) a couple of times, because i am so in love with them (you can't imagine the effect that BBX code had on my mental health)
    re: OO
    agreed - i think OO is cool for complex modules (DBI, Tk, etc.), where inheritance and friends actually make sense - but my apps that simply use all that funcionality tend to be a lot cleaner without OO...
    re: templates
    for 'normal' websites i guess i'd agree, but right now i'm working on this intranet-thing, and since basically all content is generated by my html-creator-subs, and formatted on the fly according to the data, i doubt that they would help me a lot right now..
    re: CGI::App
    I still don't get that one..i use the good ol' if ($in{action} eq "foo") style, and simply refuse to believe that using subs instead of conditionals make that much of a difference...
    re: PM-style
    very cool theory why perlmonks code they way they seem to!

      . . . this meditation was in part inspired by the fear that ina couple of years, some poor schmuck will have to look at my code the same dazzled way i've been looking at that BBX stuff.

      Heh, I often wonder the same thing about my code. Often, I end up being that poor schmuck and end up cursing myself. Actually, I consider this a good thing--it means I learned something between then and now.

      i've always used it in the 'old school' way of getting my params (via Vars()) with it

      Nothing wrong with Vars()--it's just param() in disguise :) As long as you're not doing it by hand, you're OK.

      i prefer using my own header-generators and HTML-printing subs.

      Note that even in simple cases (outputing HTML, no cookies, etc.), CGI has already avoided problems for you:

      $ perl -e 'use CGI qw(:standard); print header();' Content-Type: text/html; charset=ISO-8859-1

      Notice the addition of charset. I don't remember the specifics, but that avoids a potential cross-site scripting vulnerability.

      Every time I thought I knew how to do CGIs safely, I find out about a new edge case that was already handled by CGI.pm, such as the above. Which is why I stick to it or one of its alternate cousins.

      As for HTML creator subs, I think the case would be much stronger for them if Perl lacked a good templating system. As it happens, Perl has a lot of good templating systems (too many, some might say). Even if your project doesn't have an HTML specialist, I find templates are often easier to work with than mucking with code.

      i frankly tried it a couple of times, but got annoyed by the a bit over-pedantic messages makeing a big fuss about nothing too serious.

      Other then strict 'refs' (and only in very specific situations, like automatic generation of accsessors/mutators with closures), I've never seen strict give an error that wasn't serious. Maybe the code appeared to work, but it could have caused problems that would only be caught once it hit production.

      As I noted, warnings is occasionally bothersome, but usually the same rules apply as for strict.

      I still don't get that one..i use the good ol' if ($in{action} eq "foo") style, and simply refuse to believe that using subs instead of conditionals make that much of a difference...

      I'm currently on a project that uses CGI::Application that as of this posting has 65 run modes, and will probably get a few more before it's done. The dispatch table that CGI::Application means that each run mode is called in O(1) time, instead of O(n) worst-case as it would be with a conditional tree. So it's more efficient, if nothing else.

      Further, I keep all the run modes in a hash at the top of the applications, which is much easier to read then a huge conditional tree. Thanks to etags, my editor can jump directly to any run mode with two key strokes with the cursur over the desired mode in that hash (which is really nice, since this module is over 3000 lines long).

      Lastly, CGI::Application has already done some things for me, such as loading HTML::Template files and doing the output to the browser.

      One thing I don't like about it is that you can't write to the browser on your own, but have to return the complete output at the end of the sub. This is a major problem for one part of my application, where reports are generated from a database. The reports could get quite large--larger than I'd want to load into memory at once if I could avoid it.

      ----
      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

        One thing I don't like about it is that you can't write to the browser on your own, but have to return the complete output at the end of the sub. This is a major problem for one part of my application, where reports are generated from a database. The reports could get quite large--larger than I'd want to load into memory at once if I could avoid it.

        You can do something like this, if you want:

        sub mymode { #... print $self->_send_headers; # print your data; $self->teardown; exit( 0 ); }

        This is the method suggested on the CGI::App wiki to do an "early exit."

        --
        "To err is human, but to really foul things up you need a computer." --Paul Ehrlich