package DuckInterface; use Carp; my @inheritors; sub import { my $caller = caller; push @inheritors, $caller; } my @abstract_methods = qw(swim fly); sub INIT { my $bad = 0; for my $class (@inheritors) { for my $meth (@abstract_methods) { no strict 'refs'; unless (defined &{"${class}::$meth"}) { $bad=1; warn "Class $class should implement DuckInterface, but does not define $meth.\n"; } } } croak "Compilation aborted" if $bad; } 1; #### package RedDuck; use DuckInterface; sub swim { "I swim like a red duck"; } sub fly { "I fly like a red duck, and DuckInterface guarantees I do!"; }