http://www.perlmonks.org?node_id=515760

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

Fellow Monasterians,

Am brand new to CGI::Application and have run into a problem where it is not performing a subroutine from within one of the run modes. I've stripped it down to the basics. Here's my main.

#!/usr/local/bin/perl use lib "../cgi-bin/cgiwrap/dsoft/"; use strict; use DSAdmin_test; my $dsadmin = DSAdmin_test->new(); $dsadmin->run();

And my application:

#DSAdmin package DSAdmin_test; use strict; use warnings; use CGI::Carp qw(fatalsToBrowser); use Data::Dumper; use base 'CGI::Application'; #------------------------ redirection ------------------------ sub setup { my $self = shift; $self->mode_param('rm'); $self->run_modes( 'ss' => 'save_subsrbr', ); } sub save_subsrbr { my @errors = qw(incorrect wrong); if (@errors) { errorhandler (\@errors); return "here2: " . Dumper(@errors); } } sub errorhandler { my $errors = shift; return "here1: " . Dumper($errors); } 1;

"here2" is printing but it's not going to "here1" first! When I run the subroutines as regular Perl scripts, it works fine. What am I not getting? Thanks in advance.


—Brad
"The important work of moving the world forward does not wait to be done by perfect men." George Eliot

Replies are listed 'Best First'.
Re: CGI::Application and subroutines
by BUU (Prior) on Dec 10, 2005 at 23:10 UTC
    Your error handler simply returns "here1", in your save_subsrbr method, you call errorhandler in void context, which means you throw away the return value of the errorhandler. If you want the return value of errorhandler to be output, you need to specifically save it and print it.

      Thanks BUU (and [Limbic~Region who msg me), but I not quite sure I'm getting it. Let me explain what's going on in my actual script. If there is an error, the error handler sets up a HTML::Template page using the associate attribute, and uses CGI::Application::Plugin::FillInForm to set any check boxes, etc. and then exits the script by outputing the form with the error, along with any messages.

      Here's more of the script

      if (@errors) { errorhandler (\@errors, "subscribers", $fifvalues); }; sub errorhandler { my @errorlist; my $errors = shift; my $tmplpage = shift; my $fifvalues = shift; foreach (@$errors) { my %one_record = (errormsg => $_); push (@errorlist, \%one_record); } $template = $self->load_tmpl($tmplpage.'.tmpl', associate => $query, die_on_bad_params => 0); $template->param( errorlist => \@errorlist); my $html_output = $self->fill_form( \$template->output, $fifvalues +); return $html_output; #exits application }

      Can you show me what the code might look like that preserves this return value? Thanks!


      —Brad
      "The important work of moving the world forward does not wait to be done by perfect men." George Eliot

        Unless you start messing around with print (which I wouldn't recommend until you understand CGI::App more), CGI::App will only display what you explictly return from a runmode.

        So to show the results of another sub that your runmode calls, you need to get it's results into your runmode's return:-

        # Perhaps like this... return errorhandler(\@errors) . "here2: " . Dumper(@errors); # ...or this... my $errors = errorhandler(\@errors); return $errors . "here2: " . Dumper(@errors);

            --k.


        Update: s/would/wouldn't/;

Re: CGI::Application and subroutines
by johnnywang (Priest) on Dec 11, 2005 at 07:42 UTC
    as was pointed out earlier, you're throwing away the error message. If you want to show "here1:", try:
    sub save_subsrbr { my @errors = qw(incorrect wrong); if (@errors) { my $err = errorhandler (\@errors); return "$err, here2: " . Dumper(@errors); } }

      Thanks johnnyywang and Kanji, I think I get it now. The fact that return was printing my html page had me thinking it was replacing print (since you're not to be using the latter without care). But I'm learning that return is simply doing what returns always do. I guess I need to peak under the hood and see exactly where the C::A source code is outputing my page.

      Before C::A in my life, I would just exit through my errorhandler routine by print $output. But it looks like I have to be more tidy and "return" gracefully.


      —Brad
      "The important work of moving the world forward does not wait to be done by perfect men." George Eliot