use Devel::Symdump; sub make_animal { my $sound = shift; my @animals_that_make_sound = grep { eval { $_->isa( 'Animal' ) && $_->makes_sound eq $sound } } Devel::Symdump->rnew->packages; die "more than one animal can $sound\n" if @animals_that_make_sound > 1; die "no animals $sound\n" unless @animals_that_make_sound; return $animals_that_make_sound[0]->new; } print make_animal( 'oink' );