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]