summaryrefslogtreecommitdiff
path: root/lib/Tie
diff options
context:
space:
mode:
authorDaniel Chetlin <daniel@chetlin.com>2000-10-20 19:57:03 -0700
committerJarkko Hietaniemi <jhi@iki.fi>2000-10-21 18:06:05 +0000
commit91a014520df45f1a0c23cb5b0cb0a01ecdb2f746 (patch)
treeb6ef1f15c10dc95bc39bbbc400e8773b386fd37b /lib/Tie
parent5280a8e547c932ec16f016299ba615241bc09a38 (diff)
downloadperl-91a014520df45f1a0c23cb5b0cb0a01ecdb2f746.tar.gz
Re: [ID 20001020.002] Tie::Array SPLICE method is buggy
Message-ID: <20001021025703.A2115@darkstar.chetlin.org> p4raw-id: //depot/perl@7393
Diffstat (limited to 'lib/Tie')
-rw-r--r--lib/Tie/Array.pm74
1 files changed, 35 insertions, 39 deletions
diff --git a/lib/Tie/Array.pm b/lib/Tie/Array.pm
index e3b85d412e..f4c6193596 100644
--- a/lib/Tie/Array.pm
+++ b/lib/Tie/Array.pm
@@ -34,47 +34,43 @@ sub POP
$val;
}
-sub SPLICE
-{
- my $obj = shift;
- my $sz = $obj->FETCHSIZE;
- my $off = (@_) ? shift : 0;
- $off += $sz if ($off < 0);
- my $len = (@_) ? shift : $sz - $off;
- my @result;
- for (my $i = 0; $i < $len; $i++)
- {
- push(@result,$obj->FETCH($off+$i));
- }
- if (@_ > $len)
- {
- # Move items up to make room
- my $d = @_ - $len;
- my $e = $off+$len;
- $obj->EXTEND($sz+$d);
- for (my $i=$sz-1; $i >= $e; $i--)
- {
- my $val = $obj->FETCH($i);
- $obj->STORE($i+$d,$val);
+sub SPLICE {
+ my $obj = shift;
+ my $sz = $obj->FETCHSIZE;
+ my $off = (@_) ? shift : 0;
+ $off += $sz if ($off < 0);
+ my $len = (@_) ? shift : $sz - $off;
+ $len += $sz - $off if $len < 0;
+ my @result;
+ for (my $i = 0; $i < $len; $i++) {
+ push(@result,$obj->FETCH($off+$i));
}
- }
- elsif (@_ < $len)
- {
- # Move items down to close the gap
- my $d = $len - @_;
- my $e = $off+$len;
- for (my $i=$off+$len; $i < $sz; $i++)
- {
- my $val = $obj->FETCH($i);
- $obj->STORE($i-$d,$val);
+ $off = $sz if $off > $sz;
+ $len -= $off + $len - $sz if $off + $len > $sz;
+ if (@_ > $len) {
+ # Move items up to make room
+ my $d = @_ - $len;
+ my $e = $off+$len;
+ $obj->EXTEND($sz+$d);
+ for (my $i=$sz-1; $i >= $e; $i--) {
+ my $val = $obj->FETCH($i);
+ $obj->STORE($i+$d,$val);
+ }
}
- $obj->STORESIZE($sz-$d);
- }
- for (my $i=0; $i < @_; $i++)
- {
- $obj->STORE($off+$i,$_[$i]);
- }
- return @result;
+ elsif (@_ < $len) {
+ # Move items down to close the gap
+ my $d = $len - @_;
+ my $e = $off+$len;
+ for (my $i=$off+$len; $i < $sz; $i++) {
+ my $val = $obj->FETCH($i);
+ $obj->STORE($i-$d,$val);
+ }
+ $obj->STORESIZE($sz-$d);
+ }
+ for (my $i=0; $i < @_; $i++) {
+ $obj->STORE($off+$i,$_[$i]);
+ }
+ return @result;
}
sub EXISTS {