package PseudoHash; use strict; use warnings; use List::Util qw/max/; # Constructor # Params: # $self = Existing object reference or package # @fields = Field names to be created in the new pseudo hash # Returns: # A new blessed object sub new { my ($self, @fields) = @_; my ($class, $layout) = do { if (my $class = ref $self) { ($class, $self->[0]); } else { ($self, {}); } }; if (@fields > 0) { $layout = { %$layout }; my $offset = max(0, values %$layout) + 1; foreach my $field (@fields) { $layout->{$field} = $offset++; } } bless [ $layout ], $class; } # Accesses a field of the pseudo hash by name # Params: # $self = Reference to the pseudo hash # $field = Name of the field # Returns: # An lvalue representing the field sub field : lvalue { my ($self, $field) = @_; my $offset = $self->[0]->{$field}; die "No such field '$field' in $self" unless (defined $offset); $self->[$offset]; }