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