in reply to CGI::Application same function code

$self->run_modes( start => sub { shift->_runmode('start'); }, middle => sub { shift->_runmode('middle'); }, end => sub { shift->_runmode('end'); }, ); # ... sub _runmode { my $self = shift; my $html = shift; my $dbh = $self->param('dbh'); #.... my $tmpl_sub = $self->load_tmpl($html . '.phtml'); #... }
is one way. Another is to reverse it. The setup stays the same as you have now, but create a new function to do the actual output:
sub showStart { my $self = shift; # function specific code ... return $self->display_tmpl( file => 'start.phtml', # other parms ); } sub display_tmpl { my $self = shift; my %opts = shift; my $tmpl = $self->load_tmpl('main.phtml'); my $tmpl_sub = $self->load_tmpl($opts{file}); #... use other parms... $tmpl->param(tmpl_sub => $tmpl_sub->output()); return $tmpl->output(); }
The latter is close to how I do it.

Update:Missed my open-code tag. Fixed.

Update:Oh, and a couple other monks alerted me to the previous update ... just as I was noticing/fixing, but thanks to those who politely smacked me in private. :-)

Replies are listed 'Best First'.
Re^2: CGI::Application same function code
by boboson (Monk) on Feb 13, 2005 at 11:50 UTC
    Thanks for your reply it contained some intresting new approaches some that I understood and some that I didn't.

    I think I read somewhere on the C:A mailing list that you could only use a function name as a runmode, what exactly are you doing here:

    start => sub { shift->_runmode('start'); },
    I understand that you call the _runmode function with the argument 'start' but besides that?? Could you send in other arguments, objects as well?

    However, In the examples I still need to add the cgi object-, dbh code in the showStart function to be able to get the function specific code to work.

    I somehow want my functions to inherit from one function that has all the basic code such as: self, cgi object, dbh, output etc.

      You can use either a function name, or a code reference. (Trust me - my name is in there for providing a patch to this area.) By giving an anonymous sub here, I'm creating a code reference which gets passed in. Then C::A will call it something like: $self->$function(). This means that the first (and only) parameter is the C::A object, which above I shift off to use to call _runmode.

      You can send in anything else that is visible at the point you're setting up run modes. There is not really a lot of point to doing so in this case, however, since you can just as easily put all of that information into $self->param() and everyone else would have access to those as well.

      As for getting the CGI, DBI, and other objects/data, I don't think there is a better way than what you're already doing. What you're looking for is a templating mechanism (on CPAN, Source Filters - I've never used source filters, but just a casual read around here for the last month has shown a number of concerns around using them - they can be quite dangerous). This is not part of standard programming languages - in C/C++, you would need to use the preprocessor. In Perl, a source filter. Maybe something along the lines of a macro that you put in your code, "RUNMODE_SETUP;", which your source filter could catch and insert the real setup code. It does seem a bit overkill to me, and you do have to be careful, but it may work.