Re: inheritance and Apache::Request
sub new { my ($class, $r) = @_; return bless { r = Apache::Request-new($r), }, $class; } or sub new { my ($class,$r) = @_; my $self = $class-SUPER::new($r); # do your own init ... return $self } TMTOWTDI, aaron -- aaron ross . alias i, inc email . [EMAIL PROTECTED] phone . 215 545 6428
Re: inheritance and Apache::Request
Paul Lindner wrote: If you look you'll see that the new() method is written in C. It should be blessing itself into the passed in class, not using Apache::Request. You're right- except that this is exactly how the Apache class, from which Apache::Request is derived, expects to be subclassed. It requires all derived classes to override new(). My XS is a little foggy, but it appears that these lines should be modified to use the passed in class: CLEANUP: apreq_add_magic(ST(0), robj, RETVAL); which ends up as: ST(0) = sv_newmortal(); sv_setref_pv(ST(0), Apache::Request, (void*)RETVAL); No- that code in Request.c comes from this line in the libapreq typemap: T_APROBJ sv_setref_pv($arg, \${ntype}\, (void*)$var); $ntype is converted to Apache::Request by xsubpp. We could pull the package info from SvPV(class), but then the same fix probably should be incorporated into modperl as well. In any case all you need to do to get around this is define your own new method and call the Apache::Request object directly and store it as the value 'r'.. Here's an example: sub new { my ($class, $r) = @_; return bless { r = Apache::Request-new($r), }, $class; } Yes, exactly. sv_2apreq will look for an Apache::Request object attribute in the r or _r keys: the behavior is consistent with the eagle's Chapter 7 section on Subclassing the Apache Class: To be successful, the new subclass must add Apache (or another Apache subclass) to its @ISA array. In addition, the subclass's new() method must return a blessed hash reference which contains either an r or _r key. This key must point to a bona fide Apache object. The reason this also works OK with a derived class like Apache::Request is that an the ApacheRequest C struct has a request_rec pointer as its *first* attribute, so a cast from (ApacheRequest *) to (request_rec *) will be safe. -- Joe Schaefer
inheritance and Apache::Request
I am slowly learning about OO from Tom's tutorial, and was able to do inheritance with two dummy classes I wrote, including adding methods to the subclass and have them work too. However, when I tried to inherit from Apache::Request, it doesn't seem to work right. Maybe this isn't an Apache::Request issue, so forgive me if that's the case, but here's what I got: FooBar.pm - package FooBar; use strict; use Apache::Request(); @FooBar::ISA = qw(Apache::Request); sub fooey { print hello world, I'm in FooBar; } - Handler.pm - sub handler { my $r = shift; $r-send_http_header('text/html'); my $form = FooBar-new($r); $form-fooey; $r-exit(OK); } Here's the error I get: [Thu Feb 14 12:35:14 2002] [error] Can't locate object method fooey via package Apache::Request (perhaps you forgot to load Apache::Request?) at /path/modified/Handler.pm line 21.
Re: inheritance and Apache::Request
Alex Porras wrote: I am slowly learning about OO from Tom's tutorial, and was able to do inheritance with two dummy classes I wrote, including adding methods to the subclass and have them work too. However, when I tried to inherit from Apache::Request, it doesn't seem to work right. Maybe this isn't an Apache::Request issue, so forgive me if that's the case, but here's what I got: we have a few examples of how to subclass Apache::Request... http://www.modperlcookbook.org/code/ch10/Cookbook/TransformRequest.pm http://www.modperlcookbook.org/code/ch13/Cookbook/CookieAuthentication.pm unfortunately, the explanations are not online. recipe 10.8 talks about this in a fair amount of detail... --Geoff
Re: inheritance and Apache::Request
Hi Alex, The problem is that package FooBar doesn't have a new method. Here's what happened as a result. When you called 'FooBar-new($r), perl looked for a sub called new in package FooBar. Since it didn't find one, it looked at FooBar's @ISA, and looked in Apache::Request for a new method. There it presumably found one, so that statement didn't return an error. But, the new() in Apache::Request probably returned an Apache::Request object instead of a FooBar object, so when you called $form-fooey, it only looked in Apache::Request and any modules in it's @ISA. You might want to look at using the universal isa and can methods while you're debugging and trying stuff out. Good luck! Wes Sheldahl Alex Porras [EMAIL PROTECTED] on 02/14/2002 01:44:20 PM To: mod perl list [EMAIL PROTECTED] cc:(bcc: Wesley Sheldahl/Lex/Lexmark) Subject: inheritance and Apache::Request I am slowly learning about OO from Tom's tutorial, and was able to do inheritance with two dummy classes I wrote, including adding methods to the subclass and have them work too. However, when I tried to inherit from Apache::Request, it doesn't seem to work right. Maybe this isn't an Apache::Request issue, so forgive me if that's the case, but here's what I got: FooBar.pm - package FooBar; use strict; use Apache::Request(); @FooBar::ISA = qw(Apache::Request); sub fooey { print hello world, I'm in FooBar; } - Handler.pm - sub handler { my $r = shift; $r-send_http_header('text/html'); my $form = FooBar-new($r); $form-fooey; $r-exit(OK); } Here's the error I get: [Thu Feb 14 12:35:14 2002] [error] Can't locate object method fooey via package Apache::Request (perhaps you forgot to load Apache::Request?) at /path/modified/Handler.pm line 21.
RE: inheritance and Apache::Request
Ok, that makes sense. But the reason I didn't include a new method for FooBar was because I don't know what A::R's new method does, so I didn't want to override it. What if it does some init stuff to the object? I'm assuming that's what's happening because, after adding a new method to FooBar, when I try to call $foobar-param (which I have not overridden), the child process segfaults. Oh well, I guess at this point I need to go back to reading more on perl OO since it's not sinking. Thanks for your help! --Alex -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] The problem is that package FooBar doesn't have a new method. Here's what happened as a result. When you called 'FooBar-new($r), perl looked for a sub called new in package FooBar. Since it didn't find one, it looked at FooBar's @ISA, and looked in Apache::Request for a new method. There it presumably found one, so that statement didn't return an error. But, the new() in Apache::Request probably returned an Apache::Request object instead of a FooBar object, so when you called $form-fooey, it only looked in Apache::Request and any modules in it's @ISA. You might want to look at using the universal isa and can methods while you're debugging and trying stuff out. Good luck! Wes Sheldahl
Re: inheritance and Apache::Request
On Thu, Feb 14, 2002 at 01:55:34PM -0600, Alex Porras wrote: Ok, that makes sense. But the reason I didn't include a new method for FooBar was because I don't know what A::R's new method does, so I didn't want to override it. What if it does some init stuff to the object? I'm assuming that's what's happening because, after adding a new method to FooBar, when I try to call $foobar-param (which I have not overridden), the child process segfaults. Oh well, I guess at this point I need to go back to reading more on perl OO since it's not sinking. I believe that Apache::Request doesn't really do inheritence properly. If you look you'll see that the new() method is written in C. It should be blessing itself into the passed in class, not using Apache::Request. My XS is a little foggy, but it appears that these lines should be modified to use the passed in class: CLEANUP: apreq_add_magic(ST(0), robj, RETVAL); which ends up as: ST(0) = sv_newmortal(); sv_setref_pv(ST(0), Apache::Request, (void*)RETVAL); In any case all you need to do to get around this is define your own new method and call the Apache::Request object directly and store it as the value 'r'.. Here's an example: sub new { my ($class, $r) = @_; return bless { r = Apache::Request-new($r), }, $class; } Thanks for your help! --Alex -Original Message- From: [EMAIL PROTECTED] [mailto:[EMAIL PROTECTED]] The problem is that package FooBar doesn't have a new method. Here's what happened as a result. When you called 'FooBar-new($r), perl looked for a sub called new in package FooBar. Since it didn't find one, it looked at FooBar's @ISA, and looked in Apache::Request for a new method. There it presumably found one, so that statement didn't return an error. But, the new() in Apache::Request probably returned an Apache::Request object instead of a FooBar object, so when you called $form-fooey, it only looked in Apache::Request and any modules in it's @ISA. You might want to look at using the universal isa and can methods while you're debugging and trying stuff out. Good luck! Wes Sheldahl -- Paul Lindner[EMAIL PROTECTED] | | | | | | | | | | mod_perl Developer's Cookbook http://www.modperlcookbook.org/ Human Rights Declaration http://www.unhchr.ch/udhr/index.htm