package AbstractBase; use strict; use warnings; use Carp qw/confess/; use Storable qw/dclone/; my %DEF_INTERFACE = ( methods => [], mutators => [], ); use vars qw/%INTERFACES/; sub import { my ($self, $caller) = (shift, caller); %INTERFACES{$caller} = dclone { (%DEF_INTERFACE), @_ }; } sub AUTOLOAD { my $self = shift; (my $method = $AUTOLOAD) =~ s/(.*::)//; my $interface = $INTERFACES{$1}; croak "Abstract method not instantiated: $method" if grep /^$method$/, @{$interface->{methods}}; croak "Mutator method not instantiated: $method" if grep /^$method$/, @{$interface->{mutators}}; croak "Undefined interface component: $method"; }