$obj->[0] = 'foo';
$obj->[1] = 'bar';
$obj->[2] = 'baz';
vs
$obj->{'foo'} = 'foo';
$obj->{'bar'} = 'bar';
$obj->{'baz'} = 'baz';
####
package Class::Of::Obj;
my $foo_idx = 0;
my $bar_idx = 1;
my $baz_idx = 2;
$obj->[$foo_idx] = 'foo';
$obj->[$bar_idx] = 'bar';
$obj->[$baz_idx] = 'baz';
####
package Super::Class;
my $foo_idx = 0;
my $bar_idx = 1;
my $baz_idx = 2;
package Sub::Class;
# err...now what? How do I start using the next open index?
# Everything's hardwired up there and the Super::Class
# isn't telling me. I'm stuck.
####
package Super::Class;
my $idx = 0;
sub NEXT_IDX { return $idx++ };
use constant FOO_IDX => NEXT_IDX();
use constant BAR_IDX => FOO_IDX + 1;
use constant BAZ_IDX => BAZ_IDX + 2;
package Sub::Class;
# need to wrap in BEGIN blocks so SUPER:: works in the use at
# compile time.
BEGIN {our @ISA = qw(Super::Class)};
use constant OTHER_IDX => __PACKAGE__>SUPER::NEXT_IDX();
# oops! NEXT_IDX() is still set to '0' up there, and we just set
# OTHER_IDX to 1, clobbering whatever's in the BAR_IDX field!
####
package Super::Class;
use constant FOO_IDX => NEXT_IDX(); # 0
use constant BAR_IDX => NEXT_IDX(); # 1
use constant BAZ_IDX => NEXT_IDX(); # 2
package Sub::Class;
# need to wrap in BEGIN blocks so SUPER:: works in the use at
# compile time.
BEGIN {our @ISA = qw(Super::Class)};
use constant OTHER_IDX => __PACKAGE__>SUPER::NEXT_IDX();
#now at 3, after BAZ_IDX
####
package Super::Class;
use constant FOO_IDX => NEXT_IDX(); # 0
use constant BAR_IDX => NEXT_IDX(); # 1
use constant BAZ_IDX => NEXT_IDX(); # 2
package Sub::Class;
# need to wrap in BEGIN blocks so SUPER:: works in the use at
# compile time.
BEGIN {our @ISA = qw(Super::Class)};
use constant OTHER_IDX => __PACKAGE__>SUPER::NEXT_IDX();
#now at 3, after BAZ_IDX
package Other::Sub::Class;
BEGIN {our @ISA = qw(Super::Class)};
use constant DIFFERENT_IDX => __PACKAGE__>SUPER::NEXT_IDX();
#now at 4, after OTHER_IDX
####
package Super::Class;
use constant FOO_IDX => NEXT_IDX(); # 0
use constant BAR_IDX => NEXT_IDX(); # 1
use constant BAZ_IDX => NEXT_IDX(); # 2
package Other::Sub::Class;
# need to wrap in BEGIN blocks so SUPER:: works in the use at
# compile time.
BEGIN {our @ISA = qw(Super::Class)};
use constant DIFFERENT_IDX => __PACKAGE__>SUPER::NEXT_IDX();
#now at 3, DIFFERENT THAN LAST TIME
package Sub::Class;
BEGIN {our @ISA = qw(Super::Class)};
use constant OTHER_IDX => __PACKAGE__>SUPER::NEXT_IDX();
#now at 4, DIFFERENT THAN LAST TIME!
####
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
####
package Distant::Sub::Class;
our @ISA = qw(Sub::Class Other::Sub::Class);
#both OTHER_IDX and DIFFERENT_IDX point to index 3. Whoops.
####
package Super::Class;
# now store a global class_idx in addition to the individual
# indexes on each class
my $class_idx = 0;
sub NEXT_CLASS_IDX { return $class_idx++ };
my $class_indexes = {};
sub NEXT_IDX {
my $class = shift;
return $class_indexes->{$class}++;
}
use constant CLASS_IDX => __PACKAGE__->NEXT_CLASS_IDX();
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 CLASS_IDX => __PACKAGE__->NEXT_CLASS_IDX();
use constant DIFFERENT_IDX => __PACKAGE__->SUPER::NEXT_IDX();
#set to 0
package Sub::Class;
BEGIN {our @ISA = qw(Super::Class)};
use constant CLASS_IDX => __PACKAGE__->NEXT_CLASS_IDX();
use constant OTHER_IDX => __PACKAGE__->SUPER::NEXT_IDX();
#also set to 0
####
my $obj = Sub::Class->new();
$obj->[CLASS_IDX]->[OTHER_IDX];