package Foo;
my %attrs = map { $_ => 1 } qw/ this that /;
AUTOLOAD {
my ($m) = our $AUTOLOAD =~ /.*::(.*)/s;
return if $m eq 'DESTROY';
if ($attrs{$m}) {
print "OK: $m";
}
else {
print "Failure: $m";
# Here you need to emulate perl error message.
# Note that you don't want to use the Carp
# module for this.
}
}
####
Foo::->this; # OK: this
Foo::->that; # OK: that
Foo::->these; # Failure: these
####
package Foo::Bar;
use base 'Foo';
my %attrs = map { $_ => 1 } qw/ hah heh /;
AUTOLOAD {
my ($m) = our $AUTOLOAD =~ /.*::(.*)/s;
return if $m eq 'DESTROY';
if ($attrs{$m}) {
print "OK: $m";
}
else {
print "Failure: $m";
}
}
####
Foo::Bar::->hah; # OK: hah
Foo::Bar::->heh; # OK: heh
Foo::Bar::->hoh; # Failure: hoh
####
Foo::Bar::->this; # Failure: this
Foo::Bar::->that; # Failure: that
####
package Foo::Bar;
use base 'Foo';
my %attrs = map { $_ => 1 } qw/ hah heh /;
AUTOLOAD {
my ($m) = our $AUTOLOAD =~ /.*::(.*)/s;
return if $m eq 'DESTROY';
if ($attrs{$m}) {
print "OK: $AUTOLOAD";
}
else {
my $self = shift;
if ($self->can('SUPER::AUTOLOAD')) {
return $self->${\"SUPER::$m"}(@_);
}
else {
print "Failure: $AUTOLOAD";
}
}
}
####
{
package A;
my %attrs = map { $_ => 1 } qw/ xism /;
AUTOLOAD {
my ($m) = our $AUTOLOAD =~ /.*::(.*)/s;
return if $m eq 'DESTROY';
if ($attrs{$m}) {
print "OK: $AUTOLOAD";
}
else {
print "Failure: $AUTOLOAD";
}
}
}
{
package B;
my %attrs = map { $_ => 1 } qw/ yism /;
AUTOLOAD {
my ($m) = our $AUTOLOAD =~ /.*::(.*)/s;
return if $m eq 'DESTROY';
if ($attrs{$m}) {
print "OK: $AUTOLOAD";
}
else {
print "Failure: $AUTOLOAD";
}
}
}
####
A::->xism; # OK: A::xism
B::->yism; # OK: B::yism
####
package AB;
use base 'A', 'B';
####
AB::->xism; # OK: AB::xism
AB::->yism; # Failure: AB::yism