I prefer a ref to a blessed array with constants noting which member data is stored at which array index:
...
my $offset;
BEGIN {
$offset= 0; # Or BaseClass->_GetMaxOffset();
for my $attrib ( qw/ foo bar baz / ) {
eval "sub _$attrib() { $offset }; 1"
or die $@;
$offset++;
}
}
sub _GetMaxOffset { $offset }
# Example method
sub Foo {
my $me= shift @_;
my $old= $me->[_foo];
if( @_ ) {
my $new= shift @_;
# validate here
$me->[_foo]= $new;
}
return $old;
}
You can get compile-time catching of mispelt attribute names, faster and more compact objects, minimal increase in code complexity.
Updated: Dropped the extra "my" inside the BEGIN block as pointed out by vhold (Thanks!).