You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Richard Clarke <ri...@likewhoa.com> on 2002/11/06 16:55:09 UTC
OO handlers
List,
Tired of having 10 modules all with near identical handler methods I
decided to put the handler method into a superclass and be done with
maintaining the same code 10 times. I first tried this a couple of weeks ago
and it failed to work, because at the time I couldn't find the reference to
OO style handler methods in my Eagle book. Since the mod_perl cookbook is
now available on safari I had a quick flick through and noticed a brief
mention on OO style handler methods along with the snippet of info I needed
i.e. sub handler ($$).
To cut a long story short my subclasses are now empty (for the moment) and
they inherit (or a least should be doing) from the main superclass.
Something like,
use Control/Super.pm
@Control::Super::Sub::ISA = Control::Super;
I use a "dispatch" module with a basic handler to choose which module will
process a particular uri.
It now adds the module to be called like follows,
my $sub = join '::', 'Control', ucfirst $module, ucfirst $sub_stage;
$r->push_handlers('PerlHandler',$sub->handler);
The meaning of $module and $sub_stage is unimportant here.
And the Superclass handler looks like
sub handler ($$) {
my $self = shift;
my $r = Apache::Request->instance(shift);
# do stuff
}
Testing this with httpd -X causes a segfault every time I go to the URL. So
my question is, before I try to figure out why it segv's, is this kind of
thing allowed?, or is there some caveat which prevents handlers being
invoked if they come from a supeclass?
All help appreciated as usual,
Richard.
Re: OO handlers
Posted by Geoffrey Young <ge...@modperlcookbook.org>.
Michael Schout wrote:
> Geoffrey Young wrote:
>
>> interesting. the last time I tried was with bleedperl before 5.8 was
>> released - I know it worked then because I was writing a patch for
>> mod_perl core based on it. this thread has most of the dialogue:
>
>
>
> Hrm. Well, not sure how the :method attribute is implemented, but what
> I was trying to do was create a :Profiled attribute handler.
ah. :method is implemented in Perl core, while Attribute::Handlers is
not - see the attributes manpage for a list of built-in attributes.
>
> I tried just putting a CHECK block with a warn in my application, and it
> is true that the the CHECK block never gets called. So given that it
> seems impossible that the Attribute::Handlers module can work under
> mod_perl.
I think that Apache::Handlers uses Attribute::Handlers, so maybe
there's some secret in James' code there that could help you unlock
your Attribute::Handlers issues.
http://www.cpan.org/modules/by-module/Apache/Apache-Handlers-0.02.tar.gz
>
> Given that though, I dont doubt that the :method handler works for you
> :). Maybe this is implemented as a special case in mod_perl??
it's Perl's special case, not mod_perl's I think :)
HTH
--Geoff
Re: OO handlers
Posted by Michael Schout <ms...@gkg.net>.
Geoffrey Young wrote:
> interesting. the last time I tried was with bleedperl before 5.8 was
> released - I know it worked then because I was writing a patch for
> mod_perl core based on it. this thread has most of the dialogue:
Hrm. Well, not sure how the :method attribute is implemented, but what
I was trying to do was create a :Profiled attribute handler. So in my
base class I had:
use Attribute::Handlers;
sub Profiled ATTR(CODE) { ... }
and in a subclass:
sub foo :Profiled {
}
but I was never able to get the Profiled handler to get called. I
looked into Attribute::Handlers and it has INIT and CHECK blocks that
set up the handlers in it, so I suspected this might be the problem.
Doug claims that CHECK blocks dont work because perl calls CHECK blocks
during perl_parse(), which only happens once at startup. So he said
that it doesnt work for the same reason that:
perl -e 'eval qq(CHECK { print "hello world" })'
doesnt work.
I tried just putting a CHECK block with a warn in my application, and it
is true that the the CHECK block never gets called. So given that it
seems impossible that the Attribute::Handlers module can work under
mod_perl.
Given that though, I dont doubt that the :method handler works for you
:). Maybe this is implemented as a special case in mod_perl??
Mike
Re: OO handlers
Posted by Geoffrey Young <ge...@modperlcookbook.org>.
Michael Schout wrote:
> Geoffrey Young wrote:
>
>> keep in mind that neither book mentions the use of subroutine
>> attributes, which is allowed in 1.3 but the only way in 2.0
>>
>> sub handler : method {
>> ...
>> }
>
>
>
> I am 99% sure that Attribute handlers wont work in 1.3 because
> Attribute::Handlers use CHECK{} blocks to set up the handlers. CHECK
> blocks do not work in mod_perl under Apache 1.3 (search the list
> archives for the reason). So because CHECK blocks never execute in
> mod_perl under Apache 1.3 attribute handlers wont work. I tried to get
> them work in under Apache 1.3 a few months ago, and gave up because of
> the CHECK restrictions.
interesting. the last time I tried was with bleedperl before 5.8 was
released - I know it worked then because I was writing a patch for
mod_perl core based on it. this thread has most of the dialogue:
http://marc.theaimsgroup.com/?t=99789776100010&w=2&r=1
and below is the test I was using at the time. when trying it now
with my dev environment (Apache/1.3.28-dev (Unix) mod_perl/1.27_01-dev
Perl/v5.9.0) it works as I'd expect - the first two calls below are
broken, but the last two report back
self: My::MethodTest, r: Apache=SCALAR(0x838e850)
anyway, maybe we have different assumptions, but it seems to be
working as I would expect with the current versions.
--Geoff
package My::MethodTest;
# remember to PerlModule My::MethodTest
use Apache::Constants qw(OK);
use strict;
sub handler {
my $r = shift;
$r->push_handlers($r->current_callback => \&foo);
$r->push_handlers($r->current_callback => \&bar);
$r->push_handlers($r->current_callback => 'My::MethodTest->foo');
$r->push_handlers($r->current_callback => 'My::MethodTest->bar');
return OK;
}
sub foo : method {
my $self = shift;
my $r = shift;
print STDERR "My::Method::foo\n";
print STDERR "self: $self, r: $r\n";
return OK;
}
sub bar ($$) {
my $self = shift;
my $r = shift;
print STDERR "My::Method::bar\n";
print STDERR "self: $self, r: $r\n";
return OK;
}
1;
Re: OO handlers
Posted by Michael Schout <ms...@gkg.net>.
Geoffrey Young wrote:
> keep in mind that neither book mentions the use of subroutine
> attributes, which is allowed in 1.3 but the only way in 2.0
>
> sub handler : method {
> ...
> }
I am 99% sure that Attribute handlers wont work in 1.3 because
Attribute::Handlers use CHECK{} blocks to set up the handlers. CHECK
blocks do not work in mod_perl under Apache 1.3 (search the list
archives for the reason). So because CHECK blocks never execute in
mod_perl under Apache 1.3 attribute handlers wont work. I tried to get
them work in under Apache 1.3 a few months ago, and gave up because of
the CHECK restrictions.
Mike
Re: OO handlers
Posted by Geoffrey Young <ge...@modperlcookbook.org>.
Richard Clarke wrote:
> List,
> Tired of having 10 modules all with near identical handler methods I
> decided to put the handler method into a superclass and be done with
> maintaining the same code 10 times. I first tried this a couple of weeks ago
> and it failed to work, because at the time I couldn't find the reference to
> OO style handler methods in my Eagle book. Since the mod_perl cookbook is
> now available on safari I had a quick flick through and noticed a brief
> mention on OO style handler methods along with the snippet of info I needed
> i.e. sub handler ($$).
as you've probably discovered, you're using a feature called 'method
handlers' and you should be able to find examples in the eagle book as
well.
keep in mind that neither book mentions the use of subroutine
attributes, which is allowed in 1.3 but the only way in 2.0
sub handler : method {
...
}
[snip]
>
> I use a "dispatch" module with a basic handler to choose which module will
> process a particular uri.
> It now adds the module to be called like follows,
> my $sub = join '::', 'Control', ucfirst $module, ucfirst $sub_stage;
> $r->push_handlers('PerlHandler',$sub->handler);
even though you figured it out already, you might want to check out
how Apache::Dispatch does it - there are some security concerns that
have been addressed there that you might be interested in.
BTW, for anyone going to ApacheCon this month, I'll be giving a 2 hour
presentation on OO mod_perl techniques.
http://www.apachecon.com/html/session-popup.html?id=669
the actual contents differ a bit from the outline - if you were at
YAPC::NA it's pretty much the same as the middle part of that talk.
basically, the first 25% is about standard OO like sub handler ($$),
while the rest shows how to do augment core mod_perl via some really
cool subclassing.
cya there
--Geoff
Re: OO handlers
Posted by Richard Clarke <ri...@likewhoa.com>.
Now I feel stupid. $sub->handler was supposed to be "$sub->handler".
That's what you get for being impatient.
Ric
----- Original Message -----
From: "Richard Clarke" <ri...@likewhoa.com>
To: "Richard Clarke" <ri...@likewhoa.com>; <mo...@perl.apache.org>
Sent: Wednesday, November 06, 2002 4:08 PM
Subject: Re: OO handlers
> I should add that this segv only happens when using push_handlers like
> below. If I put Control::Super::Sub->handler inside a <Location> tag in
> httpd.conf then it is fine.
>
> Ric
>
> ----- Original Message -----
> From: "Richard Clarke" <ri...@likewhoa.com>
> To: <mo...@perl.apache.org>
> Sent: Wednesday, November 06, 2002 3:55 PM
> Subject: OO handlers
>
>
> > List,
> > Tired of having 10 modules all with near identical handler methods I
> > decided to put the handler method into a superclass and be done with
> > maintaining the same code 10 times. I first tried this a couple of weeks
> ago
> > and it failed to work, because at the time I couldn't find the reference
> to
> > OO style handler methods in my Eagle book. Since the mod_perl cookbook
is
> > now available on safari I had a quick flick through and noticed a brief
> > mention on OO style handler methods along with the snippet of info I
> needed
> > i.e. sub handler ($$).
> >
> > To cut a long story short my subclasses are now empty (for the moment)
and
> > they inherit (or a least should be doing) from the main superclass.
> > Something like,
> > use Control/Super.pm
> > @Control::Super::Sub::ISA = Control::Super;
> >
> > I use a "dispatch" module with a basic handler to choose which module
will
> > process a particular uri.
> > It now adds the module to be called like follows,
> > my $sub = join '::', 'Control', ucfirst $module, ucfirst $sub_stage;
> > $r->push_handlers('PerlHandler',$sub->handler);
> >
> > The meaning of $module and $sub_stage is unimportant here.
> >
> > And the Superclass handler looks like
> > sub handler ($$) {
> > my $self = shift;
> > my $r = Apache::Request->instance(shift);
> > # do stuff
> > }
> >
> > Testing this with httpd -X causes a segfault every time I go to the URL.
> So
> > my question is, before I try to figure out why it segv's, is this kind
of
> > thing allowed?, or is there some caveat which prevents handlers being
> > invoked if they come from a supeclass?
> >
> > All help appreciated as usual,
> > Richard.
> >
> >
> >
> >
>
>
>
>
Re: OO handlers
Posted by Richard Clarke <ri...@likewhoa.com>.
I should add that this segv only happens when using push_handlers like
below. If I put Control::Super::Sub->handler inside a <Location> tag in
httpd.conf then it is fine.
Ric
----- Original Message -----
From: "Richard Clarke" <ri...@likewhoa.com>
To: <mo...@perl.apache.org>
Sent: Wednesday, November 06, 2002 3:55 PM
Subject: OO handlers
> List,
> Tired of having 10 modules all with near identical handler methods I
> decided to put the handler method into a superclass and be done with
> maintaining the same code 10 times. I first tried this a couple of weeks
ago
> and it failed to work, because at the time I couldn't find the reference
to
> OO style handler methods in my Eagle book. Since the mod_perl cookbook is
> now available on safari I had a quick flick through and noticed a brief
> mention on OO style handler methods along with the snippet of info I
needed
> i.e. sub handler ($$).
>
> To cut a long story short my subclasses are now empty (for the moment) and
> they inherit (or a least should be doing) from the main superclass.
> Something like,
> use Control/Super.pm
> @Control::Super::Sub::ISA = Control::Super;
>
> I use a "dispatch" module with a basic handler to choose which module will
> process a particular uri.
> It now adds the module to be called like follows,
> my $sub = join '::', 'Control', ucfirst $module, ucfirst $sub_stage;
> $r->push_handlers('PerlHandler',$sub->handler);
>
> The meaning of $module and $sub_stage is unimportant here.
>
> And the Superclass handler looks like
> sub handler ($$) {
> my $self = shift;
> my $r = Apache::Request->instance(shift);
> # do stuff
> }
>
> Testing this with httpd -X causes a segfault every time I go to the URL.
So
> my question is, before I try to figure out why it segv's, is this kind of
> thing allowed?, or is there some caveat which prevents handlers being
> invoked if they come from a supeclass?
>
> All help appreciated as usual,
> Richard.
>
>
>
>