package B; sub new { my $class = shift; # ignore my $type = shift; if ($type == 1) { return D1->new(@_); } elsif ($type == 2) { return D2->new(@_); } else { return undef; } } # more as appropriate package D1; @D1::ISA = qw( B ); sub new { # paranoia check # you may not want this and I haven't tested it anyway return unless caller eq 'B'; # more as appropriate } package D2; @D2::ISA = qw( B ); sub new { # you may not want this and I haven't tested it anyway return unless caller eq 'B'; }