Minor naming change UTF8_IS_ASCII => UTF8_IS_INVARIANT
[p5sagit/p5-mst-13.2.git] / lib / Tie / Array.pm
CommitLineData
a60c0954 1package Tie::Array;
17f410f9 2
3use 5.005_64;
a60c0954 4use strict;
01020589 5use Carp;
17f410f9 6our $VERSION = '1.01';
ab3c8535 7
a60c0954 8# Pod documentation after __END__ below.
9
10sub DESTROY { }
7517970f 11sub EXTEND { }
12sub UNSHIFT { scalar shift->SPLICE(0,0,@_) }
13sub SHIFT { shift->SPLICE(0,1) }
14#sub SHIFT { (shift->SPLICE(0,1))[0] }
a60c0954 15sub CLEAR { shift->STORESIZE(0) }
16
7517970f 17sub PUSH
18{
a60c0954 19 my $obj = shift;
20 my $i = $obj->FETCHSIZE;
21 $obj->STORE($i++, shift) while (@_);
22}
23
7517970f 24sub POP
a60c0954 25{
26 my $obj = shift;
27 my $newsize = $obj->FETCHSIZE - 1;
28 my $val;
7517970f 29 if ($newsize >= 0)
a60c0954 30 {
31 $val = $obj->FETCH($newsize);
e5724059 32 $obj->STORESIZE($newsize);
a60c0954 33 }
34 $val;
7517970f 35}
a60c0954 36
91a01452 37sub SPLICE {
38 my $obj = shift;
39 my $sz = $obj->FETCHSIZE;
40 my $off = (@_) ? shift : 0;
41 $off += $sz if ($off < 0);
42 my $len = (@_) ? shift : $sz - $off;
43 $len += $sz - $off if $len < 0;
44 my @result;
45 for (my $i = 0; $i < $len; $i++) {
46 push(@result,$obj->FETCH($off+$i));
a60c0954 47 }
91a01452 48 $off = $sz if $off > $sz;
49 $len -= $off + $len - $sz if $off + $len > $sz;
50 if (@_ > $len) {
51 # Move items up to make room
52 my $d = @_ - $len;
53 my $e = $off+$len;
54 $obj->EXTEND($sz+$d);
55 for (my $i=$sz-1; $i >= $e; $i--) {
56 my $val = $obj->FETCH($i);
57 $obj->STORE($i+$d,$val);
58 }
a60c0954 59 }
91a01452 60 elsif (@_ < $len) {
61 # Move items down to close the gap
62 my $d = $len - @_;
63 my $e = $off+$len;
64 for (my $i=$off+$len; $i < $sz; $i++) {
65 my $val = $obj->FETCH($i);
66 $obj->STORE($i-$d,$val);
67 }
68 $obj->STORESIZE($sz-$d);
69 }
70 for (my $i=0; $i < @_; $i++) {
71 $obj->STORE($off+$i,$_[$i]);
72 }
73 return @result;
7517970f 74}
a60c0954 75
01020589 76sub EXISTS {
77 my $pkg = ref $_[0];
78 croak "$pkg dosn't define an EXISTS method";
79}
80
81sub DELETE {
82 my $pkg = ref $_[0];
83 croak "$pkg dosn't define a DELETE method";
84}
85
a60c0954 86package Tie::StdArray;
87use vars qw(@ISA);
88@ISA = 'Tie::Array';
89
90sub TIEARRAY { bless [], $_[0] }
7517970f 91sub FETCHSIZE { scalar @{$_[0]} }
92sub STORESIZE { $#{$_[0]} = $_[1]-1 }
a60c0954 93sub STORE { $_[0]->[$_[1]] = $_[2] }
94sub FETCH { $_[0]->[$_[1]] }
95sub CLEAR { @{$_[0]} = () }
7517970f 96sub POP { pop(@{$_[0]}) }
a60c0954 97sub PUSH { my $o = shift; push(@$o,@_) }
7517970f 98sub SHIFT { shift(@{$_[0]}) }
99sub UNSHIFT { my $o = shift; unshift(@$o,@_) }
01020589 100sub EXISTS { exists $_[0]->[$_[1]] }
101sub DELETE { delete $_[0]->[$_[1]] }
a60c0954 102
103sub SPLICE
104{
7517970f 105 my $ob = shift;
a60c0954 106 my $sz = $ob->FETCHSIZE;
107 my $off = @_ ? shift : 0;
108 $off += $sz if $off < 0;
109 my $len = @_ ? shift : $sz-$off;
110 return splice(@$ob,$off,$len,@_);
111}
ab3c8535 112
1131;
114
115__END__
116
117=head1 NAME
118
119Tie::Array - base class for tied arrays
120
7517970f 121=head1 SYNOPSIS
ab3c8535 122
a60c0954 123 package NewArray;
ab3c8535 124 use Tie::Array;
a60c0954 125 @ISA = ('Tie::Array');
3cb6de81 126
a60c0954 127 # mandatory methods
7517970f 128 sub TIEARRAY { ... }
129 sub FETCH { ... }
130 sub FETCHSIZE { ... }
3cb6de81 131
a60c0954 132 sub STORE { ... } # mandatory if elements writeable
133 sub STORESIZE { ... } # mandatory if elements can be added/deleted
01020589 134 sub EXISTS { ... } # mandatory if exists() expected to work
135 sub DELETE { ... } # mandatory if delete() expected to work
3cb6de81 136
a60c0954 137 # optional methods - for efficiency
7517970f 138 sub CLEAR { ... }
139 sub PUSH { ... }
140 sub POP { ... }
141 sub SHIFT { ... }
142 sub UNSHIFT { ... }
143 sub SPLICE { ... }
144 sub EXTEND { ... }
a60c0954 145 sub DESTROY { ... }
146
147 package NewStdArray;
148 use Tie::Array;
3cb6de81 149
a60c0954 150 @ISA = ('Tie::StdArray');
151
152 # all methods provided by default
153
154 package main;
155
156 $object = tie @somearray,Tie::NewArray;
157 $object = tie @somearray,Tie::StdArray;
158 $object = tie @somearray,Tie::NewStdArray;
159
160
ab3c8535 161
7517970f 162=head1 DESCRIPTION
ab3c8535 163
a60c0954 164This module provides methods for array-tying classes. See
165L<perltie> for a list of the functions required in order to tie an array
01020589 166to a package. The basic B<Tie::Array> package provides stub C<DESTROY>,
167and C<EXTEND> methods that do nothing, stub C<DELETE> and C<EXISTS>
168methods that croak() if the delete() or exists() builtins are ever called
169on the tied array, and implementations of C<PUSH>, C<POP>, C<SHIFT>,
170C<UNSHIFT>, C<SPLICE> and C<CLEAR> in terms of basic C<FETCH>, C<STORE>,
a60c0954 171C<FETCHSIZE>, C<STORESIZE>.
172
7517970f 173The B<Tie::StdArray> package provides efficient methods required for tied arrays
a60c0954 174which are implemented as blessed references to an "inner" perl array.
7517970f 175It inherits from B<Tie::Array>, and should cause tied arrays to behave exactly
176like standard arrays, allowing for selective overloading of methods.
a60c0954 177
178For developers wishing to write their own tied arrays, the required methods
179are briefly defined below. See the L<perltie> section for more detailed
180descriptive, as well as example code:
181
bbc7dcd2 182=over 4
a60c0954 183
184=item TIEARRAY classname, LIST
185
186The class method is invoked by the command C<tie @array, classname>. Associates
187an array instance with the specified class. C<LIST> would represent
188additional arguments (along the lines of L<AnyDBM_File> and compatriots) needed
189to complete the association. The method should return an object of a class which
7517970f 190provides the methods below.
a60c0954 191
192=item STORE this, index, value
193
8dcee03e 194Store datum I<value> into I<index> for the tied array associated with
a60c0954 195object I<this>. If this makes the array larger then
196class's mapping of C<undef> should be returned for new positions.
197
198=item FETCH this, index
199
8dcee03e 200Retrieve the datum in I<index> for the tied array associated with
a60c0954 201object I<this>.
202
203=item FETCHSIZE this
204
8dcee03e 205Returns the total number of items in the tied array associated with
a60c0954 206object I<this>. (Equivalent to C<scalar(@array)>).
ab3c8535 207
a60c0954 208=item STORESIZE this, count
209
8dcee03e 210Sets the total number of items in the tied array associated with
a60c0954 211object I<this> to be I<count>. If this makes the array larger then
212class's mapping of C<undef> should be returned for new positions.
213If the array becomes smaller then entries beyond count should be
7517970f 214deleted.
a60c0954 215
216=item EXTEND this, count
217
218Informative call that array is likely to grow to have I<count> entries.
219Can be used to optimize allocation. This method need do nothing.
220
01020589 221=item EXISTS this, key
222
223Verify that the element at index I<key> exists in the tied array I<this>.
224
225The B<Tie::Array> implementation is a stub that simply croaks.
226
227=item DELETE this, key
228
229Delete the element at index I<key> from the tied array I<this>.
230
231The B<Tie::Array> implementation is a stub that simply croaks.
232
a60c0954 233=item CLEAR this
234
8dcee03e 235Clear (remove, delete, ...) all values from the tied array associated with
a60c0954 236object I<this>.
237
238=item DESTROY this
239
240Normal object destructor method.
241
7517970f 242=item PUSH this, LIST
a60c0954 243
244Append elements of LIST to the array.
245
246=item POP this
247
248Remove last element of the array and return it.
249
250=item SHIFT this
251
252Remove the first element of the array (shifting other elements down)
253and return it.
254
7517970f 255=item UNSHIFT this, LIST
a60c0954 256
8dcee03e 257Insert LIST elements at the beginning of the array, moving existing elements
a60c0954 258up to make room.
259
260=item SPLICE this, offset, length, LIST
261
7517970f 262Perform the equivalent of C<splice> on the array.
a60c0954 263
7517970f 264I<offset> is optional and defaults to zero, negative values count back
265from the end of the array.
a60c0954 266
267I<length> is optional and defaults to rest of the array.
268
269I<LIST> may be empty.
270
271Returns a list of the original I<length> elements at I<offset>.
272
273=back
ab3c8535 274
275=head1 CAVEATS
276
7517970f 277There is no support at present for tied @ISA. There is a potential conflict
ab3c8535 278between magic entries needed to notice setting of @ISA, and those needed to
7517970f 279implement 'tie'.
a60c0954 280
281Very little consideration has been given to the behaviour of tied arrays
282when C<$[> is not default value of zero.
283
7517970f 284=head1 AUTHOR
a60c0954 285
286Nick Ing-Simmons E<lt>nik@tiuk.ti.comE<gt>
ab3c8535 287
7517970f 288=cut