Harald Joerg
2007-10-25 09:31:23 UTC
Yesterday I've encountered a case where CGIPH isn't as DWIM as it
could be. It had never hit me before, because usually I use mod_perl
and compile all stuff in the startup routine.
The docs of CGIPH state:
... The package for the class is autoloaded if needed.
This is true as long as the class is passed to dispatch via the _state
parameter, but doesn't hold between the steps. I believe that my use
case is quite typical: In my respond routines, I want to return a
"next page". But not as a page object, as the docs, if carefully
read, require. I'd rather follow the Linux Mag article and simply
return the *name* of the class:
sub respond {
# ...whatever needs to be done in response to the user's request
return 'My::App::NextPage';
}
or even DWIMmer, but different from what's implemented in CGIP and
documented in Linux Mag:
sub respond {
# ...du whatever needs to be done in response to the user's request
return 'NextPage';
}
However, this fails if My::App::NextPage hasn't already been compiled.
It dies when trying to execute My::App::NextPage::control_enter.
Both control_enter and its caller activate are inherited from CGIP,
which doesn't support autoloading, so it isn't just a one-liner in
CGIPH. Currently I'm using the following workaround in My::App:
sub respond {
my $self = shift;
my $package = $self->respond_per_app ||
$self->respond_per_page;
eval "require $package" unless (ref $package ||
eval "defined %${package}::");
die if $@;
return $package;
}
I am not completely happy with it since it prevents simple
applications to override respond (as in the Linux Mag example, which
admittedly refers to CGIP). I need to stick to respond_per_page
instead. Maybe it would be better to override activate in CGIPH and
do the autoloading immediately before $next_page->control_enter?
could be. It had never hit me before, because usually I use mod_perl
and compile all stuff in the startup routine.
The docs of CGIPH state:
... The package for the class is autoloaded if needed.
This is true as long as the class is passed to dispatch via the _state
parameter, but doesn't hold between the steps. I believe that my use
case is quite typical: In my respond routines, I want to return a
"next page". But not as a page object, as the docs, if carefully
read, require. I'd rather follow the Linux Mag article and simply
return the *name* of the class:
sub respond {
# ...whatever needs to be done in response to the user's request
return 'My::App::NextPage';
}
or even DWIMmer, but different from what's implemented in CGIP and
documented in Linux Mag:
sub respond {
# ...du whatever needs to be done in response to the user's request
return 'NextPage';
}
However, this fails if My::App::NextPage hasn't already been compiled.
It dies when trying to execute My::App::NextPage::control_enter.
Both control_enter and its caller activate are inherited from CGIP,
which doesn't support autoloading, so it isn't just a one-liner in
CGIPH. Currently I'm using the following workaround in My::App:
sub respond {
my $self = shift;
my $package = $self->respond_per_app ||
$self->respond_per_page;
eval "require $package" unless (ref $package ||
eval "defined %${package}::");
die if $@;
return $package;
}
I am not completely happy with it since it prevents simple
applications to override respond (as in the Linux Mag example, which
admittedly refers to CGIP). I need to stick to respond_per_page
instead. Maybe it would be better to override activate in CGIPH and
do the autoloading immediately before $next_page->control_enter?
--
Cheers,
haj
Cheers,
haj