This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
new perldelta
[perl5.git] / t / op / tiearray.t
CommitLineData
93965878
NIS
1#!./perl
2
3BEGIN {
4 chdir 't' if -d 't';
af5c7f63 5 require './test.pl';
624c42e2 6 set_up_inc('../lib');
93965878
NIS
7}
8
47ff51ce
DM
9plan(tests => 75);
10
93965878
NIS
11my %seen;
12
13package Implement;
14
c5ccff6f
DM
15sub TIEARRAY {
16 $seen{'TIEARRAY'}++;
17 my ($class,@val) = @_;
18 return bless \@val,$class;
93965878
NIS
19}
20
c5ccff6f
DM
21sub STORESIZE {
22 $seen{'STORESIZE'}++;
23 my ($ob,$sz) = @_;
24 return $#{$ob} = $sz-1;
93965878
NIS
25}
26
c5ccff6f
DM
27sub EXTEND {
28 $seen{'EXTEND'}++;
29 my ($ob,$sz) = @_;
30 return @$ob = $sz;
93965878
NIS
31}
32
c5ccff6f
DM
33sub FETCHSIZE {
34 $seen{'FETCHSIZE'}++;
35 return scalar(@{$_[0]});
93965878
NIS
36}
37
c5ccff6f
DM
38sub FETCH {
39 $seen{'FETCH'}++;
40 my ($ob,$id) = @_;
41 return $ob->[$id];
93965878
NIS
42}
43
c5ccff6f
DM
44sub STORE {
45 $seen{'STORE'}++;
46 my ($ob,$id,$val) = @_;
47 $ob->[$id] = $val;
48}
93965878 49
c5ccff6f
DM
50sub UNSHIFT {
51 $seen{'UNSHIFT'}++;
52 my $ob = shift;
53 unshift(@$ob,@_);
54}
93965878 55
c5ccff6f
DM
56sub PUSH {
57 $seen{'PUSH'}++;
58 my $ob = shift;;
59 push(@$ob,@_);
60}
93965878 61
c5ccff6f
DM
62sub CLEAR {
63 $seen{'CLEAR'}++;
64 @{$_[0]} = ();
a60c0954
NIS
65}
66
c5ccff6f
DM
67sub DESTROY {
68 $seen{'DESTROY'}++;
93965878
NIS
69}
70
c5ccff6f
DM
71sub POP {
72 $seen{'POP'}++;
73 my ($ob) = @_;
74 return pop(@$ob);
93965878
NIS
75}
76
c5ccff6f
DM
77sub SHIFT {
78 $seen{'SHIFT'}++;
79 my ($ob) = @_;
80 return shift(@$ob);
93965878
NIS
81}
82
c5ccff6f
DM
83sub SPLICE {
84 $seen{'SPLICE'}++;
85 my $ob = shift;
86 my $off = @_ ? shift : 0;
87 my $len = @_ ? shift : @$ob-1;
88 return splice(@$ob,$off,$len,@_);
93965878
NIS
89}
90
6f12eb6d
MJD
91package NegIndex; # 20020220 MJD
92@ISA = 'Implement';
93
94# simulate indices -2 .. 2
95my $offset = 2;
96$NegIndex::NEGATIVE_INDICES = 1;
97
98sub FETCH {
c5ccff6f
DM
99 my ($ob,$id) = @_;
100 #print "# FETCH @_\n";
101 $id += $offset;
102 $ob->[$id];
6f12eb6d
MJD
103}
104
105sub STORE {
c5ccff6f
DM
106 my ($ob,$id,$value) = @_;
107 #print "# STORE @_\n";
108 $id += $offset;
109 $ob->[$id] = $value;
6f12eb6d
MJD
110}
111
112sub DELETE {
c5ccff6f
DM
113 my ($ob,$id) = @_;
114 #print "# DELETE @_\n";
115 $id += $offset;
116 delete $ob->[$id];
6f12eb6d
MJD
117}
118
119sub EXISTS {
c5ccff6f
DM
120 my ($ob,$id) = @_;
121 #print "# EXISTS @_\n";
122 $id += $offset;
123 exists $ob->[$id];
6f12eb6d 124}
93965878 125
22846ab4
AB
126#
127# Returning -1 from FETCHSIZE used to get casted to U32 causing a
128# segfault
129#
130
131package NegFetchsize;
132
133sub TIEARRAY { bless [] }
134sub FETCH { }
135sub FETCHSIZE { -1 }
136
93965878 137
c5ccff6f 138package main;
93965878 139
c5ccff6f 140{
47ff51ce 141 $seen{'DESTROY'} = 0;
c5ccff6f
DM
142 my @ary;
143
144 {
145 my $ob = tie @ary,'Implement',3,2,1;
146 ok($ob);
147 is(tied(@ary), $ob);
148 }
149
150 is(@ary, 3);
151 is($#ary, 2);
152 is(join(':',@ary), '3:2:1');
153 cmp_ok($seen{'FETCH'}, '>=', 3);
154
155 @ary = (1,2,3);
156
157 cmp_ok($seen{'STORE'}, '>=', 3);
158 is(join(':',@ary), '1:2:3');
159
160 {
161 my @thing = @ary;
162 is(join(':',@thing), '1:2:3');
163
164 tie @thing,'Implement';
165 @thing = @ary;
166 is(join(':',@thing), '1:2:3');
167 }
47ff51ce 168 is($seen{'DESTROY'}, 1, "thing freed");
c5ccff6f
DM
169
170 is(pop(@ary), 3);
171 is($seen{'POP'}, 1);
172 is(join(':',@ary), '1:2');
173
174 is(push(@ary,4), 3);
175 is($seen{'PUSH'}, 1);
176 is(join(':',@ary), '1:2:4');
177
178 my @x = splice(@ary,1,1,7);
179
180 is($seen{'SPLICE'}, 1);
181 is(@x, 1);
182 is($x[0], 2);
183 is(join(':',@ary), '1:7:4');
184
185 is(shift(@ary), 1);
186 is($seen{'SHIFT'}, 1);
187 is(join(':',@ary), '7:4');
188
189 my $n = unshift(@ary,5,6);
190 is($seen{'UNSHIFT'}, 1);
191 is($n, 4);
192 is(join(':',@ary), '5:6:7:4');
193
194 @ary = split(/:/,'1:2:3');
195 is(join(':',@ary), '1:2:3');
196
197 my $t = 0;
198 foreach $n (@ary) {
199 is($n, ++$t);
200 }
201
202 # (30-33) 20020303 mjd-perl-patch+@plover.com
203 @ary = ();
204 $seen{POP} = 0;
205 pop @ary; # this didn't used to call POP at all
206 is($seen{POP}, 1);
207 $seen{SHIFT} = 0;
208 shift @ary; # this didn't used to call SHIFT at all
209 is($seen{SHIFT}, 1);
210 $seen{PUSH} = 0;
211 my $got = push @ary; # this didn't used to call PUSH at all
212 is($got, 0);
213 is($seen{PUSH}, 1);
214 $seen{UNSHIFT} = 0;
215 $got = unshift @ary; # this didn't used to call UNSHIFT at all
216 is($got, 0);
217 is($seen{UNSHIFT}, 1);
218
219 @ary = qw(3 2 1);
220 is(join(':',@ary), '3:2:1');
221
222 $#ary = 1;
223 is($seen{'STORESIZE'}, 1, 'seen STORESIZE');
224 is(join(':',@ary), '3:2');
225
226 sub arysize :lvalue { $#ary }
227 arysize()--;
228 is($seen{'STORESIZE'}, 2, 'seen STORESIZE');
229 is(join(':',@ary), '3');
230
231 untie @ary;
93965878 232}
47ff51ce 233is($seen{'DESTROY'}, 2, "ary freed");
cf8feb78
MJD
234
235# 20020401 mjd-perl-patch+@plover.com
11ec0460 236# Thanks to Dave Mitchell for the small test case and the fix
74d0c54f 237{
c5ccff6f
DM
238 my @a;
239
240 sub X::TIEARRAY { bless {}, 'X' }
241
242 sub X::SPLICE {
243 do '/dev/null';
244 die;
245 }
246
247 tie @a, 'X';
248 eval { splice(@a) };
249 # If we survived this far.
250 pass();
cf8feb78 251}
6f12eb6d 252
c5ccff6f
DM
253# 20020220 mjd-perl-patch+@plover.com
254{
47ff51ce
DM
255 $seen{'DESTROY'} = 0;
256
c5ccff6f
DM
257 my @n;
258 tie @n => 'NegIndex', ('A' .. 'E');
259
260 # FETCH
261 is($n[0], 'C');
262 is($n[1], 'D');
263 is($n[2], 'E');
264 is($n[-1], 'B');
265 is($n[-2], 'A');
266
267 # STORE
268 $n[-2] = 'a';
269 is($n[-2], 'a');
270 $n[-1] = 'b';
271 is($n[-1], 'b');
272 $n[0] = 'c';
273 is($n[0], 'c');
274 $n[1] = 'd';
275 is($n[1], 'd');
276 $n[2] = 'e';
277 is($n[2], 'e');
278
279 # DELETE and EXISTS
280 for (-2 .. 2) {
281 ok($n[$_]);
282 delete $n[$_];
283 is(defined($n[$_]), '');
284 is(exists($n[$_]), '');
285 }
6f12eb6d 286}
47ff51ce 287is($seen{'DESTROY'}, 1, "n freed");
6f12eb6d 288
22846ab4
AB
289{
290 tie my @dummy, "NegFetchsize";
291 eval { "@dummy"; };
af5c7f63
NC
292 like($@, qr/^FETCHSIZE returned a negative value/,
293 " - croak on negative FETCHSIZE");
22846ab4
AB
294}
295
8b0c3377
DM
296{
297 # check that a tied element assigned to an array doesn't remain tied
298
299 package Magical;
300
301 my $i = 10;
302
303 sub TIEARRAY { bless [1] }
304 sub TIEHASH { bless [1] }
305 sub FETCHSIZE { 1; }
306 sub FETCH { $i++ }
307 sub STORE { $_[0][0] = $_[1]; }
308 sub FIRSTKEY { 0 }
309 sub NEXTKEY { }
310
311 package main;
312
313 my (@a, @b);
314 tie @a, 'Magical';
315 @b = @a;
316 is ($b[0], 10, "Magical array fetch 1");
317 $b[0] = 100;
318 is ($b[0], 100, "Magical array fetch 2");
319
320 my (%a, %b);
321 tie %a, 'Magical';
322 %b = %a;
323 is ($b{0}, 11, "Magical hash fetch 1");
324 $b{0} = 100;
325 is ($b{0}, 100, "Magical hash fetch 2");
326}