RA Jones wrote:
Reading the thread on 'Good practices: how many run modes in an app' it
is obvious my current application under development is going way over
the 'recommended' upper limit of rm's. I know I need to break it into
smaller units based around functionality, but how?
I had an app like this, and as a first step in refactoring, I put groups of
run modes in separate packages. I then "use" each of those sub-packages in the
main package, and give each sub-package the following import() routine:
sub import
{
caller()->add_callback( 'prerun' => sub {
my $self = shift;
$self->run_modes([EMAIL PROTECTED]);
} );
goto &Exporter::import;
}
This puts the local run modes into the main object, so the old instance script
or Apache handler (and all the associated templates and urls) still work as
before.
This gives me a separation of functionality, without having to revise every
aspect of the whole application.
Note that this works because the run_modes() method is additive: it doesn't
clear out previous contents, but simply adds the new run modes to the app.
At the moment my main application module is invoked either through an
instance script (eg myapp.cgi) or via an embedded Apache handler - it's
designed to work with both. As soon as I think of splitting the module
into smaller units I'm not sure I know how to proceed. How's this:
MyApp::Base contains all the CGI::Application override methods like
cgiapp_init, setup, cgiapp_prerun, template_pre_process, etc but no
run-modes (except perhaps session/authentication/authorisation methods).
It uses base CGI::Application.
This is a good idea regardless of how you split up your applications.
MyApp::Function_1 contains all the run-modes related to function_1 (eg
edit records) and uses base MyApp::Base ie it inherits cgiapp_init,
setup, etc from the MyAPpp::Base module (or should we use @ISA here?).
use base qw/MyApp::Base/;
or
our @ISA = qw/MyApp::Base/;
is functionally equivalent. I personally prefer the former, since it reads
better.
Other MyApp:Function_ modules are setup as needed. But the question is
how to call these modules - do they each have to have their own instance
script pointing to them (eg myapp_function_1.cgi, myapp_function_2.cgi,
etc), and an embedded Apache handler so they can run under mod_perl? One
instance script per module? If so I have to change all the templates to
point to any one of many mini-applications - in fact what we get is a
host of mini-apps running under the umbrella of a larger whole. This
seems a little complicated, almost defeating the object of breaking the
application into smaller units.
My way gives you an excuse for not having to do that just yet. However, see
also the thread about url dispatching earlier this month. We're looking at
ways to ease the pain of managing many small applications.
Or is this all completely wide of the mark? I think an example of an
application broken into multiple parts would be very helpful for me at
this stage.
Here's a sketch of my app structure as it is now. I show two parts, the main,
formerly monolithic CgiApp, and one package with a set of run modes.
package My::MainApp;
use base qw/My::BaseApp/; # I already have this one; it handles sessions etc
use My::MainApp::Admin; # contains the run modes dealing with admin functions
use My::MainApp::News; # another example package of run modes
# rest of app follows
# this app still has some runmodes of its own, but most have been moved
# into the packages use()d above.
1;
package My::MainApp::Admin;
use CGI::Application; # to get the callback functionality
use base qw/Exporter/;
sub import
{
caller()->add_callback( 'prerun' => sub {
my $self = shift;
$self->run_modes([qw/
save_user
delete_user
/]);
} );
goto &Exporter::import;
}
sub save_user {} # these used to be a run mode in MainApp
sub delete_user {} # but are now in their own package
1;
Hope that helps a bit :)
Rhesa
---------------------------------------------------------------------
Web Archive: http://www.mail-archive.com/[email protected]/
http://marc.theaimsgroup.com/?l=cgiapp&r=1&w=2
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]