Hi,

Am Mittwoch, 18. Februar 2004 00:37 schrieb Stas Bekman:
> Boris Zentner wrote:
[...]
> >>>my $c = shift;
> >>>$AUTOLOAD =~ /(\w+)$/;
> >>>$c->$1(@_);
> >>>
> >>>looks funny, but the we need to handle the return part too. That might
> >>> be not so nice for any case.
> >>
> >>Yes, that's not good. How about:
> >>
> >>         if (@modules) {
> >>             eval "require $_" for @modules;
> >>             if (@modules == 1) {
> >>                 my $module = shift @modules;
> >>                 $AUTOLOAD =~ s/.*::/$module::/;
> >>             }
> >>             goto &$AUTOLOAD;
> >>         }
> >>
> >>really, I think it should always be only one matching module, since we
> >> have no internal sub-classing at the moment.
> >
> > I can not belive, that this work.
>
> You mean it *does* work for you.

No, it does not work. 

>
> > what if my class is
> >
> > package q;
> > @ISA=('Apache::Filter', 'Apache::RequestIO');
> >
> > or look at DESTROY do we choice the right DESTROY?

some what related:
perl -MModPerl::MethodLookup -le ' \
package Apache::RequestRec; sub new { bless {}, shift }; 1; \
package My::Request; @ISA = qw(Apache::RequestRec); 1; \
package main; my $obj = My::Request->new(); \
my($hint, @modules) = ModPerl::MethodLookup::lookup_method("DESTROY", $obj); \ 
print $hint'

To use method 'DESTROY' add:
        use APR::Pool ();

but 

perl -MModPerl::MethodLookup -le ' \
package Apache::RequestRec; sub new { bless {}, shift }; 1; \
package My::Request; @ISA = qw(Apache::RequestRec); 1; \
package main; my $obj = My::Request->new(); \
my($hint, @modules) = ModPerl::MethodLookup::lookup_method("DESTROY", 
"Apache::RequestRec"); \ print $hint'

gives nothing.

>
> that is easily solvable by passing the class name the AUTOLOAD is called
> for instead of the real object.
>
> So if you call:
>
> package q;
> @ISA=('Apache::Filter', 'Apache::RequestIO');
> q->new->print();
>
> we do:
>
>   for my $module (@avail_modules) {
>      *{"$module\::AUTOLOAD"} = sub {
>          my($hint, @modules) =
>              ModPerl::MethodLookup::lookup_method($AUTOLOAD, $module);
>
> which translates into:
>
>    lookup_method('q::print', 'Apache::Filter');
>
> since inheritance tree traversal goes left to right. Meaning that it'll
> find that Apache::Filter need to be loaded and then call:
>
>    goto &Apache::Filter::print;
>
> The problem with that change is when a method which is not found in the
> first ISA class is not found. Actually the way lookup_method is implemented
> at the moment, it'll check the second argument only if it has more than 1
> hit. So if you call:
>
>    q->new->sendfile();
>
> it'll still do the right thing. Apache::Filter::AUTOLOAD will load
> Apache::RequestIO and call:
>
>    goto &Apache::RequestIO::sendfile;
>
> Regarding DESTROY, I think we are covered too. The only difference from the
> above explanation is that we don't croak if DESTROY is not found. Or do you
> see a hole in my logic?

-- 
Boris


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

Reply via email to