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

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

Replies are listed 'Best First'.
Re: Re: Re: Re: Perlmonk's "best pratices" in the real world
by LTjake (Prior) on Nov 13, 2003 at 17:49 UTC
    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