The biggest change I made was adding an else clause to B::AUTOLOAD(). If the appropriate subroutine isn't found in package B, it constructs a symbolic reference to a function in A. Since that function may not be there, it's trapped by AUTOLOAD.package A; sub bar { return "BAR"; } sub AUTOLOAD { my (@objpath) = split(/::/, $AUTOLOAD); my $fname = pop @objpath; return if $fname eq 'DESTROY'; if ( $fname eq 'baz' ) { my $subr = <<EOSUB; sub $AUTOLOAD { return "FOO"; } EOSUB eval $subr; goto &$AUTOLOAD; return $subr; } return; } package B; @ISA = qw( A ); sub new { return bless {}, shift; } sub AUTOLOAD { my (@objpath) = split(/::/, $AUTOLOAD); my $fname = pop @objpath; return if $fname eq 'DESTROY'; if ( $fname eq 'foo' ) { my $subr = <<EOSUB; sub $AUTOLOAD { return "FOO"; } EOSUB eval $subr; goto &$AUTOLOAD; } else { return &{"A::$fname"}; } return; } package main; my $b = new B; print "foo: ", $b->foo, "\n"; print "bar: ", $b->bar, "\n"; print "baz: ", $b->baz, "\n";
I have no idea whether or not this gets caching, but I'll check. It's not very clean or elegant or safe, so I wouldn't use it except in an emergency. Still, it's One Way To Do It.
In reply to Re: AUTOLOAD functions & inheritence
by chromatic
in thread AUTOLOAD functions & inheritence
by LunaticLeo
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |