Make your own array. This one specifically croaks when the size limitation would be exceeded. You can change it so that pushing to it would remove elements from the beginning if needed.
package Tie::Array::MaxLen;
use Carp;
sub TIEARRAY {
my ($class, $size) = @_;
croak "size must be positive" if $size <= 0;
return bless [ $size, [] ], $class;
}
sub check ($$) {
my ($size, $idx) = @_;
croak "index $idx out of bounds" if
$idx >= $size or
($idx < 0 and -$idx > $size);
}
sub FETCH {
my ($self, $idx) = @_;
check($self->[0], $idx);
return $self->[1][$idx];
}
sub STORE {
my ($self, $idx, $value) = @_;
check($self->[0], $idx);
return $self->[1][$idx] = $value;
}
sub FETCHSIZE {
my ($self) = @_;
return scalar @{ $self->[1] };
}
sub STORESIZE { # maybe you want this, maybe not
my ($self, $size) = @_;
croak "size must be positive" if $size <= 0;
$self->[0] = $size;
$#{ $self->[1] } = $size-1;
}
sub CLEAR {
my ($self) = @_;
$self->[1] = [];
}
sub POP {
my ($self) = @_;
return pop @{ $self->[1] };
}
sub PUSH {
my $self = shift;
check($self->[0], @_ + @{ $self->[1] });
push @{ $self->[1] }, @_;
}
sub SHIFT {
my ($self) = @_;
return shift @{ $self->[1] };
}
sub UNSHIFT {
my $self = shift;
check($self->[0], @_ + @{ $self->[1] });
unshift @{ $self->[1] }, @_;
}
sub EXISTS { # remove if not 5.6+
my ($self, $idx) = @_;
check($self->[0], $idx);
exists $self->[1][$idx];
}
sub DEFINED {
my ($self, $idx) = @_;
check($self->[0], $idx);
defined $self->[1][$idx];
}
sub SPLICE {
my $self = shift;
my $off = @_ ? shift : 0;
$off += $self->[0] if $off < 0;
my $len = @_ ? shift : $self->[0] - $off;
$len += $self->[0] if $len < 0;
check($self->[0], $off + $len);
splice(@{ $self->[1] }, $off, $len, @_);
}
As "complete" as that looks, I've not tested it. It seems like it should work though. Sample use:
tie my(@five), 'Tie::Array::MaxLen', 5;
push @five, 10, 20, 30, 40;
push @five, 50;
push @five, 60; # QUACK
japhy --
Perl and Regex Hacker |