http://qs321.pair.com?node_id=481645

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

Dearest Monks and Monkesses,

I've recently been playing around with CGI::Application which I like a lot.

Every time I add a new runmode method, though, I forget to add it to the list that must be supplied to the run_modes method in the setup phase. Consequently, every time I try to run my app with a new mode, I get an error. "This is far too much work," I hollered, and changed my run_modes invocation to this:

package MyApp; use strict; use warnings; use base 'CGI::Application'; sub setup { my $self = shift; # ... other stuff my @modes = grep /^rm_/, keys %MyApp::; $self->run_modes( map { /rm_(.*)/ => $_ } @modes ); }

Sure enough, that nicely maps ?rm=foo to the method rm_foo and I can now add modes to my heart's content.

But it does kinda give me the heebie-jeebies. Anyway,

  1. Does CGI::Application offer a better solution to what I'm doing?
  2. Or is what I'm doing a completely horrible idea in the first place?
  3. Suppose someone were to subclass MyApp and inherrit the setup method. They would get the MyApp runmodes but would not get any new modes in the subclass. Any way around that?

Much obliged, friedo

Replies are listed 'Best First'.
Re: CGI::Application - A little too lazy?
by astroboy (Chaplain) on Aug 07, 2005 at 11:39 UTC
Re: CGI::Application - A little too lazy?
by leriksen (Curate) on Aug 07, 2005 at 10:45 UTC
    We do something very similiar, but we match run modes, module and templates - run modes rm_XXX is handled by the MyApp::XXX::run(), which pulls in the HTML::Template XXX.tmpl.

    I guess if you wanted to handle inheritance, you could write some kind of BEGIN block in the derived modules that builds some kind of register at compile time, that is then used by setup() to build the CGI::App instance from. Then you just need to remember to do that for each derived module...hmmm maybe that just makes a different 'I always forget to ...' problem.

    ...it is better to be approximately right than precisely wrong. - Warren Buffet

Re: CGI::Application - A little too lazy?
by samtregar (Abbot) on Aug 07, 2005 at 15:43 UTC
    It looks to me like you traded one bit of repetitive typing (adding your mode to the run_modes list) for another (adding rm_ to the start of every runmode). I'd wager that you'll type the run mode names often enough in a complex CGI::App to make this a bad trade-off.

    -sam

      Oh, I don't know about that. The frustration in failing to remember to update my call to run_modes whenever I add a new run mode function is probably worth those extra few letters on each and every function name. It can save me minutes of debugging time, which is way less effort than typing three extra characters.

      Further, by the principle of keeping scope as minimal as possible, everything to do with a given run mode can be kept to just that function - I don't need to remember to go to the top (or bottom) of my module to add it to another data structure elsewhere. Having to set up run modes has to be my biggest issue with using C::A. Not that I have a better solution, mind you. It just is.

      It looks to me like you traded one bit of repetitive typing (adding your mode to the run_modes list) for another (adding rm_ to the start of every runmode).

      That actually doesn't bug me, since I was already naming my runmode methods rm_whatever in order to differentiate them from non-runmode methods.

Re: CGI::Application - A little too lazy?
by Anonymous Monk on Aug 07, 2005 at 10:13 UTC
    I don't remember its name, but there is an addon for CGI::Application that already does something like that.