package Super::Class; my $class_indexes = {}; sub NEXT_IDX { my $class = shift; #if we have an index for this class, then return it if (defined $class_indexes->{$class}) { return ++$class_indexes->{$class}; } else { no strict 'refs'; my @isa = @{$class . "::ISA"}; #root class has no super my $idx = @isa ? $isa[0]->CURR_IDX() : -1; $class_indexes->{$class} = $idx + 1; return $class_indexes->{$class}; } } sub CURR_IDX { my $class = shift; return $class_indexes->{$class}; } use constant FOO_IDX => __PACKAGE__->NEXT_IDX(); # 0 use constant BAR_IDX => __PACKAGE__->NEXT_IDX(); # 1 use constant BAZ_IDX => __PACKAGE__->NEXT_IDX(); # 2 package Other::Sub::Class; BEGIN {our @ISA = qw(Super::Class)}; use constant DIFFERENT_IDX => __PACKAGE__->SUPER::NEXT_IDX(); #set to 3 package Sub::Class; BEGIN {our @ISA = qw(Super::Class)}; use constant OTHER_IDX => __PACKAGE__->SUPER::NEXT_IDX(); #also set to 3