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

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

I have an app I wrote using CGI::Application. Several of the run modes make a call to a certain utility method I inherit from my base class. Now this utility method can occasionally throw an error, but the error is fixable.

When I first thought of this problem the solution seemed simple: I'd just check for the error condition inside the utility function, and if I detected it, I could simply change to a run mode that fixes it. But as far as I can tell, it's impossible to change run modes like this.

So whats way to hack around this stupid limitation? I've considered modifying Application.pm it self, but unless this would change the main version at cpan this would be really irritating to have to maintain my own forked version.


Update:
If anyone cares, my solution to this problem was basically thus:
sub utility { my $self = shift; my $query = CGI->new('rm=new_mode'); ref($self)->new->run(QUERY=>$query); exit; }

Replies are listed 'Best First'.
Re: Changing run mode in cgi::application
by aktbar (Beadle) on Mar 23, 2004 at 11:46 UTC
    It's a little unclear exactly what you're doing, but I'm guessing it's something like this (code oversimplified but I hope it's clear):
    sub myRunmodeA { my $self = shift; my $isOK = blah (foo, bar) ... } sub myRunmodeB { my $self = shift; fixBlahProblem(); ... } sub blah { return if param('problem') eq 'true'; }
    What you want to do is, if myRunmodeA finds a problem, switch to myRunmodeB. There's nothing particularly magic about the run mode -- once your CGI::Application has been brought to life by the user, you are a class, so you can just call myRunmodeB, i.e. (using code from my example above):
    sub myRunmodeA { my $self = shift; if( blah (foo, bar) ) { #usual code } else { return $self->myRunmodeB; } }

    (You might want to set the runmode before hopping into myRunmodeB, just for good luck. You probably do that with $self->{rm} = 'myRunmodeB', but this depends on how you set things up in CGI::Application:setup).

    Hope that helps!

    Alan

      While what you describe is possible, it seems ugly/annoying to have to add that logic to every single run mode that uses my utility method. It would be so much cleaner if I could just replace the currently running run_mode with a new one that handles the error, but I can't figure out how.
Re: Changing run mode in cgi::application
by matthewb (Curate) on Mar 23, 2004 at 10:43 UTC

    You can use the prerun_mode() method to change the run mode of your CGI::App.

    MB
      If you'd read the CGI::Application docs:
      The prerun_mode() method is an accessor/mutator which can be used within your cgiapp_prerun() method to change the run mode Note: The prerun_mode() method may ONLY be called in the context of a cgiapp_prerun() method. Your application will die() if you call prerun_mode() elsewhere, such as in setup() or a run mode method.
      I wish to change from one run_mode to another, so that won't work.
perldoc -f goto
by PodMaster (Abbot) on Mar 24, 2004 at 05:56 UTC
    Suprisingly enough this question comes up often and it is not a stupid limitation of CGI::Application, but a failure to understand how CGI::Application works (CGI::Application::Loop may help you visualize it). A bunch of methods get called and in one of them a runmode is chosen (usually sub setup). Then the runmode is executed and it's output returned to the browser. The only way to change the run mode from the runmode is to use goto. Make sense? Now code for it.

    MJD says "you can't just make shit up and expect the computer to know what you mean, retardo!"
    I run a Win32 PPM repository for perl 5.6.x and 5.8.x -- I take requests (README).
    ** The third rule of perl club is a statement of fact: pod is sexy.

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Changing run mode in cgi::application
by dragonchild (Archbishop) on Mar 24, 2004 at 13:28 UTC
    Read the answer I gave you on the cgiapp mailing list. The issue that you don't seem to be understanding is this: all runmodes are functions. There is nothing magical about them. If you want to change runmodes, you have to change which function returns back to the C::A function that calls runmodes.

    Here's another way to think about it - you need to change what value is returned back to the C::A function that calls runmodes. I actually have runmodes that act as traffic cops, figuring out which function actually will generate the output, depending on various conditions. Those output functions are not "runmodes".

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