Discussion:
[cgi-prototype-users] Lazy compilation for the render class in CGIP::Hidden
Harald Joerg
2007-10-25 09:31:23 UTC
Permalink
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?
--
Cheers,
haj
Andrew Gianni
2007-10-25 13:51:34 UTC
Permalink
Post by Harald Joerg
sub respond {
# ...du whatever needs to be done in response to the user's request
return 'NextPage';
}
Try:

sub respond {
my $self = shift;
return $self->name_to_page('NextPage');
}

Or is there some specific reason that you want to just return a string
instead of an object?

Andrew
--
Andrew Gianni - Lead Programmer Analyst
Administrative Computing Services / Computing and Information Technology
University at Buffalo, State University of New York
215 Millard Fillmore Academic Complex, Buffalo, NY 14261-0026
716.645.5332 - AIM: andrewsgianni - http://www.newkenmore.com/agianni
Harald Joerg
2007-10-25 14:32:32 UTC
Permalink
Post by Harald Joerg
Post by Harald Joerg
sub respond {
# ...du whatever needs to be done in response to the user's request
return 'NextPage';
}
sub respond {
my $self = shift;
return $self->name_to_page('NextPage');
}
Or is there some specific reason that you want to just return a string
instead of an object?
Yes, of course I could do that, and there is no specific reason other
than DWIM.

Writing an extra mantra $self->name_to_page() dozens of times (in
every respond, every module) is sightly annoying and gives me the
impression of a decentralized workaround.

If I write another application, which may be not before next year, I
am sure to stubmle over that again. It is not in the Linux Mag
examples, not easily collected from the PODs, and not in my own
mod_perl apps.

Currently I've flipped to overriding activate in My::App.pm., and
inserted the autoloading code immediately before the call to
$next_page->control_enter. For the moment, I like it that way :-)

That's what I like with CGIPH: The code is so slim that it is pretty
easy to understand, hence rather riskless to overload, and TIMTOWTDI!
--
Cheers,
haj
Randal L. Schwartz
2007-10-25 14:55:24 UTC
Permalink
Harald> That's what I like with CGIPH: The code is so slim that it is pretty
Harald> easy to understand, hence rather riskless to overload, and TIMTOWTDI!

Thanks! That was the point. Do just the basics. Don't go nutty.
Add things as you see fit when they are common to *all* apps.
--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<***@stonehenge.com> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!
Andrew Gianni
2007-10-25 14:49:45 UTC
Permalink
Post by Harald Joerg
Writing an extra mantra $self->name_to_page() dozens of times (in
every respond, every module) is sightly annoying and gives me the
impression of a decentralized workaround.
Actually, I just look at it as useful refactoring. We actually have
situations in some of our applications where we cross over application
classes between respond and render; i.e. The response of App1::page_x may
want to return App2::page_y at times. So simply passing the name of the page
isn't enough, we really need to return a page object with an explicit full
class name. It definitely makes sense to localize the functionality you
need, but rolling that up into CGI::Prototype would make it less flexible.
Post by Harald Joerg
If I write another application, which may be not before next year, I
am sure to stubmle over that again. It is not in the Linux Mag
examples, not easily collected from the PODs, and not in my own
mod_perl apps.
Better documentation would make this easier to understand. I reckon Randal
has written enough of the basic stuff and its up to us as a community to put
together some more in-depth tutorials. That said, I'm not exactly swimming
with spare time :) Maybe come late December early January (winter break)
I'll have some time to work on something collaboratively. Perhaps a CGIP
wiki would be a good option.

Andrew
--
Andrew Gianni - Lead Programmer Analyst
Administrative Computing Services / Computing and Information Technology
University at Buffalo, State University of New York
215 Millard Fillmore Academic Complex, Buffalo, NY 14261-0026
716.645.5332 - AIM: andrewsgianni - http://www.newkenmore.com/agianni
Loading...