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.
>
>
>
>