Hi Stas,

Am Montag, 16. Februar 2004 11:58 schrieb Stas Bekman:
> Boris Zentner wrote:
> [...]
>
> > It works better, but not right. It has the same problems as the last one,
> > but the other way around ;-)
> >
> > On my first test I found out that it is incredible slow. So iI move the
> >
> >               return if $AUTOLOAD =~ /$skip/;
> >
> > line before the lookup_method. That is not right ever, your way looks
> > much better, but it was so slow. Perhaps other ideas are around.
>
> What's slow? Are there too many calls to DESTROY? Can you add tracing to
> figure out the reason?

It was so slow that I thought it is not working at all. Yes it was eval and 
destroy. But I take a closer look later.

>
> I thought to do so originally (move it up), but there are DESTROY methods
> in some of the classes, so I don't think this is right (unless we manually
> look them up and cache and then skip lookup if it's not in the cache.
>
> > The second problem is if I have a class that inherits from another class
> > with splitted functions like Apache::RequestRec.
> >
> > package xxx;
> > @ISA='Apache::RequestRec';
> > sub new { bless $_[1], $_[0] }
> >
> > sub handler : method {
> >   my ( $class, $rec ) = @_;
> >   xxx->new( $rec )->print('hello world');
> > }
> >
> > then AUTOLOAD is called and found out, that Apache::RequestRec is the
> > superclass of xxx and that Apache::RequestIO must be loaded. We require
> > Apache::RequestRec and then goto subroutine xxx::print. That is an
> > endless loop, since it calls AUTOLOAD to find out about xxx::print. In
> > this case we must call Apache::RequestRec::print, but we do not know
> > about it we only know Apache::RequestIO.
>
> So there must be a bug in the code. That shouldn't be the case. Let's take
> the $obj->print() call for example. where $obj is a sub-class of
> Apache::RequestRec and let's say it's called My::RequestRec. The data we
> have is:
>
>            'print' => [
>                         [
>                           'Apache::RequestIO',
>                           'Apache::RequestRec'
>                         ],
>                         [
>                           'Apache::Filter',
>                           'Apache::Filter'
>                         ]
>                       ],
>
> so lookup_method internally finds two entries. none of them matches
> My::RequestRec. So it checks isa() and finds that the first entry matches.
> It should now return 'Apache::RequestIO', which AUTOLOAD loads and now when
> it calls goto, it calls that method.

Yes, that is exactly what happened here. But it is wrong. 
from your example:
        Apache::RequestIO is returned. now 
        eval { require 'Apache::RequestIO' } loads the class/package.

but the next line 'goto &$AUTOLOAD' calls My::RequestRec::print and produce 
the endless loop. Since we need to call Apache::RequestRec::print _not_ 
My::RequestRec::print.

>
> This snippet I've quoted earlier shows that method_lookup returns
> 'Apache::RequestIO'
>
> perl -MModPerl::MethodLookup -le '\
> package Apache::RequestRec; sub new { bless {}, shift }; \
> package My::Request; @ISA = qw(Apache::RequestRec); \
> package main; my $obj = My::Request->new();  \
> my($hint, @modules) = ModPerl::MethodLookup::lookup_method("print", $obj);
> \ print $hint'
> To use method 'print' add:
>          use Apache::RequestIO ();
>
> What do you see different?

I see exactly what you see. 
-- 
Boris

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

Reply via email to