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

#!C:/Perl/bin/perl.exe # index.cgi use strict; use warnings; use Auto; my $app = Auto->new(PARAMS => {my_param => 'some val'}); $app->run;
package Auto; use strict; use warnings; use base 'CGI::Application'; use Start; sub setup { my ($self) = @_; $self->start_mode('start'); $self->run_modes(start => 'start'); } sub start { my ($self) = @_; my $start = Start->new; return $start->output; } 1;
package Start; use strict; use warnings; sub new { my ($this) = @_; my $self = { #stuff }; bless $self, $this; } sub output { my ($self) = @_; my $query = # CGI::App's $self->query? my $param = # CGI::App's $self->param('my_param')? # do stuff return $output; } 1;
How can the Start::output method get hold of the CGI::App methods?

Replies are listed 'Best First'.
Re: CGI::Application - How to use a module for each runmode?
by friedo (Prior) on Feb 20, 2007 at 22:01 UTC

    How can the Start::output method get hold of the CGI::App methods?

    Just pass your CGI::App object to Start when you instantiate it.

    sub start { my ($self) = @_; my $start = Start->new( app => $self ); return $start->output; }

    And stick it in your Start object.

    package Start; use strict; use warnings; sub new { my $class = shift; my %args = @_; my $self = { app => $args{app}; }; bless $self, $class; }

    And, optionally, add an accessor method if you don't want to peek at the hashref directly.

    sub app { my $self = shift; return $self->{app}; }

    And then access the object.

    sub output { my ($self) = @_; my $query = $self->app->query; my $param = $self->app->param( 'my_param' ); # do stuff return $output; }
Re: CGI::Application - How to use a module for each runmode?
by derby (Abbot) on Feb 20, 2007 at 21:51 UTC

    The approach is kinda wonky but hey ... I would just pass what you need either to new and/or output. I would loosely couple the modules and rather than pass the objects, pass only the info I need:

    sub start { my ( $self ) = @_; my $query = $self->query(); my $foo = $query->param( 'foo' ); my $bar = $query->param( 'bar' ); my $baz = $self->param( 'my_param' ); my $start = Start->new(); $start->output( qux => $foo, quux => $bar, corge => $baz ); }

    -derby
Re: CGI::Application - How to use a module for each runmode?
by InfiniteLoop (Hermit) on Feb 20, 2007 at 21:02 UTC
    I don't understand the question, but if you pass the "$self" from Auto->start() to Start->output, you would be able to access the CGI::Application methods. Hope that helps.
Re: CGI::Application - How to use a module for each runmode?
by stonecolddevin (Parson) on Feb 21, 2007 at 05:00 UTC

    I believe this is what CGI::Application::Dispatch is for. It works a lot like the way Catalyst does in delegating which view is presented and such. If you read the docs it should be pretty clear, you can use CGI::Application::Dispatch with mod_ perl (i believe that's preferred) or you can use a CGI script to handle the "dispatching".

    Hope this helps!

    meh.
Re: CGI::Application - How to use a module for each runmode?
by Rhandom (Curate) on Feb 21, 2007 at 16:21 UTC
    I apologize for cross posting modules, but CGI::Ex::App from CGI::Ex lets you do it in either of the following ways:
    sub allow_morph { 1 } # OR my $app = MyApp->new({allow_morph => 1});

    That's all. What is then going on behind the scenes is that when a run mode is called ("step" in CGI::Ex::App) the system will see if a corresponding module exists, and if so, will re-bless the object into that class for the duration of the run mode, and then return to its former class after the run mode finishes.

    By default the module name of the run mode is the class of the running object combined with the run mode name. So, if my object was called "MyApp" and the run mode was "test_step" the class looked for would be "MyApp::TestStep". This is also easy to override though by providing a module_package hook like this.
    sub test_step_module_package { 'MyTestStepModule' }

    From this point on the application would use the MyTestStepModule class whenever the test_step_module was needed.

    The following is a complete CGI::Ex::App application that allows morphing on each step that will run from commandline, Apache/cgi, or Apache/mod_perl(1&2).
    #!/usr/bin/perl -w package Foo; use strict; use warnings; use base qw(CGI::Ex::App); Foo->navigate; sub allow_morph { 1 } package Foo::Main; use base qw(Foo); sub file_print { return \ "Great! You got here!\n" }

    Which would print the following when run from the commandline.
    Content-Type: text/html Great! You got here!

    To see everything that occurred behind the scenes you could add the following lines of code to the Foo class:
    use CGI::Ex::Dump qw(debug); sub post_navigate { debug shift->dump_history; }

    In addition to the previous output, you would now also see something similar to the following:
    debug: cgi-bin/foo.pl line 15 shift->dump_history = [ "Elapsed: 0.07506", "main - morph - morph (changed Foo to Foo::Main) - 0.00000 + - 1", "main - morph_package - morph_package - 0.00004 - Foo::Mai +n", "main - run_step - run_step - 0.03927 - 1", " main - pre_step - pre_step - 0.00001 - 0", " main - skip - skip - 0.00001 - 0", " main - prepare - prepare - 0.00001 - 1", " main - info_complete - info_complete - 0.00005 - 0", " main - ready_validate - ready_validate - 0.00001 +- 0", " main - prepared_print - prepared_print - 0.03901 - 1" +, " main - hash_base - hash_base - 0.00005 - HASH(0x8 +31890c)", " main - hash_common - hash_common - 0.00001 - {}", " main - hash_form - hash_form - 0.00002 - {}", " main - hash_fill - hash_fill - 0.00001 - {}", " main - hash_swap - hash_swap - 0.00001 - {}", " main - hash_errors - hash_errors - 0.00001 - {}", " main - print - print - 0.03871 - 1", " main - file_print - file_print - 0.00001 - SC +ALAR(0x825f7a0)", " main - swap_template - swap_template - 0.0348 +8 - Great! You got here!\n", " main - template_args - template_args - 0. +00001 - HASH(0x8335aac)", " main - fill_template - fill_template - 0.0031 +9 - 1", " main - fill_args - fill_args - 0.00001 - +{}", " main - print_out - print_out - 0.00047 - 1", " main - post_print - post_print - 0.00001 - 0", "main - unmorph - unmorph (changed from Foo::Main to Foo) +- 0.00000 - 1" ];

    The interesting portion is the morph line where it says it was changed from Foo to Foo::Main and the unmorph line where it was changed from Foo::Main back to Foo. We have been using this in production (well not this exact example) for a number of years and it has served us very well. I'm sure something vaguely similar exists for CGI::Application, and if not, it should be possible to add it.

    my @a=qw(random brilliant braindead); print $a[rand(@a)];