package Thingy; sub make_cog { my $self = shift; return Cog->new(@_); } { ... my $cog = $self->make_cog(...); ... } package MyThingy; sub make_cog { my $self = shift; return MyCog->new(@_); } #### package Thingy; sub make_cog { my $self = shift; my $cog_class = ref($self) . '::Cog'; if ($cog_class->can('new')) { return $cog_class->new(@_); } else { return Thingy::Cog->new(@_); } } #### sub make_class { my ($class, $base_class) = @_; my $isa_glob = do { no strict 'refs'; ${"${class}::"}{ISA} }; if (!$isa_glob || !*$isa_glob{ARRAY}) { @$isa = $base_class; } } { my $group = 'MyThingy'; make_class("${group}::$_', 'Thingy::$_') foreach qw( Cog Ramp Handle ); ... }