Boris Zentner wrote:
Hi Stas,

Am Donnerstag, 12. Februar 2004 18:49 schrieb Stas Bekman:

The biggest drawback for me is whenever inherence comes into play it wont
work. Method_lookup is a hack. It is nice to have, but it whould much
better if it is not needed at all.

Do you suggest that AUTOLOAD doesn't work with inheritance? Doesn't it call the right AUTOLOAD function?


Yes, AUTOLOAD has some drawbacks. During my testing I found two of them imediately.

1. You can not rely on ->can. If I have a object and ask $obj->can('print') The answer is yes it can print, or I do not know maybe we can load print try it! Thats odd. But not a mod_perl issue.

2. EazyLife can not know about my methods, so the option is guess and load all classes with methods that may satisfy me or ignore me. I dislike both and Apache::Request forwards everything unknown to the environ object, but it seems it looks what the object can ( untested ) so nothing is forwarded until the class is loaded.

Well, may be your case is much more complicated than the average case, and EazyLife could benefit a majority of users. And someone like you will have to manually figure out which modules to load. Unless you have better idea.


Back to EazyLife:
It calls the AUTOLOAD function and in my case it is the right one. But if My class is a new one ( one that is not part of mod_perl ) then ModPerl::MethodLookup simply find nothing and dies.


suppose this ( untested and useless ) example:

package SuperRequestRec;
our @ISA = qw!Apache::RequestRec!;
sub new {
my $class = shift;
return bless shift, $class;
} 1;


sub handler :method {
my ( $c, $r ) = @_; my $sr = SuperRequestRec->new( $r );
$sr->print("Hi");
return DONE;
}


see this line from EazyLife.pm

ModPerl::MethodLookup::lookup_method($AUTOLOAD, @_);

$AUTOLOAD may be SuperRequestRec::print

and $_[0] is a reference to SuperRequestRec.

I see what you mean. Try to patch it to try first:


ModPerl::MethodLookup::lookup_method($AUTOLOAD, @_);
and if it fails:

ModPerl::MethodLookup::lookup_method($AUTOLOAD);

The second argument (@_) is optional to help resolve the situation when there is more than one class with the same method. For example:

% perl -MApache2 -MModPerl::MethodLookup -e print_method new
There is more than one class with method 'new'
try one of:
        use APR::NetLib ();
        use APR::UUID ();
        use APR::Bucket ();
        use APR::Pool ();
        use Apache::RequestUtil ();
        use APR::ThreadMutex ();
        use APR::Brigade ();
%
% perl -MApache2 -MModPerl::MethodLookup -e print_method new Apache::RequestRec

To use method 'new' add:
        use Apache::RequestUtil ();

So how about this (it's untested):

----------------------------------
package EazyLife;

use ModPerl::MethodLookup ();

for my $module (ModPerl::MethodLookup::avail_modules()) {
    *{"$module\::AUTOLOAD"} = sub {
        my($hint, @modules) =
            ModPerl::MethodLookup::lookup_method($AUTOLOAD, @_);

        # handle inheritance
        unless (@modules) {
            my($hint, @super_classes) =
                ModPerl::MethodLookup::lookup_method($AUTOLOAD);
            for (@super_classes) {
                push @modules, $_ if ref($AUTOLOAD) && $AUTOLOAD->isa($_);
            }
        }

        if (@modules) {
            eval "require $_" for @modules;
            goto &$AUTOLOAD;
        }
        else {
            die $hint;
        }
    };
}

1;

----------------------------------

__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to