Commit | Line | Data |
---|---|---|
cba5a3b0 DG |
1 | #!./perl |
2 | ||
3 | BEGIN { | |
4 | chdir 't' if -d 't'; | |
cba5a3b0 | 5 | require './test.pl'; |
43011852 FC |
6 | @INC = () unless is_miniperl(); |
7 | unshift @INC, '../lib'; | |
cba5a3b0 DG |
8 | } |
9 | use strict; | |
10 | use warnings; | |
d401967c | 11 | no warnings 'deprecated', 'experimental::autoderef'; |
7ac5715b | 12 | use vars qw($data $array $values $hash $errpat); |
cba5a3b0 DG |
13 | |
14 | plan 'no_plan'; | |
15 | ||
16 | sub j { join(":",@_) } | |
17 | ||
0b3fe645 YO |
18 | # NOTE |
19 | # | |
20 | # Hash insertion is currently unstable, in that | |
21 | # %hash= %otherhash will not necessarily result in | |
22 | # the same internal ordering of the data in the hash. | |
23 | # For instance when keys collide the copy may not | |
24 | # match the inserted order. So we declare one hash | |
25 | # and then make all our copies from that, which should | |
26 | # mean all the copies have the same internal structure. | |
0e0ab621 YO |
27 | # |
28 | # And these days, even if all that weren't true, we now | |
29 | # per-hash randomize keys/values. So, we cant expect two | |
30 | # hashes with the same internal structure to return the | |
31 | # same thing at all. All we *can* expect is that keys() | |
32 | # and values() use the same ordering. | |
0b3fe645 YO |
33 | our %base_hash; |
34 | ||
cba5a3b0 | 35 | BEGIN { # in BEGIN for "use constant ..." later |
0e0ab621 YO |
36 | # values match keys here so we can easily check that keys(%hash) == values(%hash) |
37 | %base_hash= ( pi => 'pi', e => 'e', i => 'i' ); | |
cba5a3b0 | 38 | $array = [ qw(pi e i) ]; |
0e0ab621 | 39 | $values = [ qw(pi e i) ]; |
0b3fe645 | 40 | $hash = { %base_hash } ; |
cba5a3b0 | 41 | $data = { |
0b3fe645 | 42 | hash => { %base_hash }, |
cba5a3b0 DG |
43 | array => [ @$array ], |
44 | }; | |
45 | } | |
46 | ||
47 | package Foo; | |
48 | sub new { | |
49 | my $self = { | |
0b3fe645 | 50 | hash => { %base_hash }, |
cba5a3b0 DG |
51 | array => [@{$main::array}] |
52 | }; | |
53 | bless $self, shift; | |
54 | } | |
55 | sub hash { no overloading; $_[0]->{hash} }; | |
56 | sub array { no overloading; $_[0]->{array} }; | |
57 | ||
58 | package Foo::Overload::Array; | |
59 | sub new { return bless [ qw/foo bar/ ], shift } | |
60 | use overload '@{}' => sub { $main::array }, fallback => 1; | |
61 | ||
62 | package Foo::Overload::Hash; | |
63 | sub new { return bless { qw/foo bar/ }, shift } | |
64 | use overload '%{}' => sub { $main::hash }, fallback => 1; | |
65 | ||
66 | package Foo::Overload::Both; | |
67 | sub new { return bless { qw/foo bar/ }, shift } | |
68 | use overload '%{}' => sub { $main::hash }, | |
69 | '@{}' => sub { $main::array }, fallback => 1; | |
70 | ||
71 | package Foo::Overload::HashOnArray; | |
72 | sub new { return bless [ qw/foo bar/ ], shift } | |
73 | use overload '%{}' => sub { $main::hash }, fallback => 1; | |
74 | ||
75 | package Foo::Overload::ArrayOnHash; | |
76 | sub new { return bless { qw/foo bar/ }, shift } | |
77 | use overload '@{}' => sub { $main::array }, fallback => 1; | |
78 | ||
79 | package main; | |
80 | ||
0b3fe645 | 81 | use constant CONST_HASH => { %base_hash }; |
cba5a3b0 DG |
82 | use constant CONST_ARRAY => [ @$array ]; |
83 | ||
0b3fe645 | 84 | my %a_hash = %base_hash; |
cba5a3b0 DG |
85 | my @an_array = @$array; |
86 | sub hash_sub { return \%a_hash; } | |
87 | sub array_sub { return \@an_array; } | |
88 | ||
89 | my $obj = Foo->new; | |
90 | ||
91 | my ($empty, $h_expect, $a_expect, @tmp, @tmp2, $k, $v); | |
92 | ||
93 | # Keys -- void | |
94 | ||
95 | keys $hash; pass('Void: keys $hash;'); | |
96 | keys $data->{hash}; pass('Void: keys $data->{hash};'); | |
97 | keys CONST_HASH; pass('Void: keys CONST_HASH;'); | |
98 | keys CONST_HASH(); pass('Void: keys CONST_HASH();'); | |
99 | keys hash_sub(); pass('Void: keys hash_sub();'); | |
100 | keys hash_sub; pass('Void: keys hash_sub;'); | |
101 | keys $obj->hash; pass('Void: keys $obj->hash;'); | |
102 | keys $array; pass('Void: keys $array;'); | |
103 | keys $data->{array}; pass('Void: keys $data->{array};'); | |
104 | keys CONST_ARRAY; pass('Void: keys CONST_ARRAY;'); | |
105 | keys CONST_ARRAY(); pass('Void: keys CONST_ARRAY();'); | |
106 | keys array_sub; pass('Void: keys array_sub;'); | |
107 | keys array_sub(); pass('Void: keys array_sub();'); | |
108 | keys $obj->array; pass('Void: keys $obj->array;'); | |
109 | ||
110 | # Keys -- scalar | |
111 | ||
112 | is(keys $hash ,3, 'Scalar: keys $hash'); | |
113 | is(keys $data->{hash} ,3, 'Scalar: keys $data->{hash}'); | |
114 | is(keys CONST_HASH ,3, 'Scalar: keys CONST_HASH'); | |
115 | is(keys CONST_HASH() ,3, 'Scalar: keys CONST_HASH()'); | |
116 | is(keys hash_sub ,3, 'Scalar: keys hash_sub'); | |
117 | is(keys hash_sub() ,3, 'Scalar: keys hash_sub()'); | |
118 | is(keys $obj->hash ,3, 'Scalar: keys $obj->hash'); | |
119 | is(keys $array ,3, 'Scalar: keys $array'); | |
120 | is(keys $data->{array} ,3, 'Scalar: keys $data->{array}'); | |
121 | is(keys CONST_ARRAY ,3, 'Scalar: keys CONST_ARRAY'); | |
122 | is(keys CONST_ARRAY() ,3, 'Scalar: keys CONST_ARRAY()'); | |
123 | is(keys array_sub ,3, 'Scalar: keys array_sub'); | |
124 | is(keys array_sub() ,3, 'Scalar: keys array_sub()'); | |
125 | is(keys $obj->array ,3, 'Scalar: keys $obj->array'); | |
126 | ||
127 | # Keys -- list | |
128 | ||
0e0ab621 | 129 | $h_expect = j(sort keys %base_hash); |
cba5a3b0 DG |
130 | $a_expect = j(keys @$array); |
131 | ||
0e0ab621 YO |
132 | is(j(sort keys $hash) ,$h_expect, 'List: sort keys $hash'); |
133 | is(j(sort keys $data->{hash}) ,$h_expect, 'List: sort keys $data->{hash}'); | |
134 | is(j(sort keys CONST_HASH) ,$h_expect, 'List: sort keys CONST_HASH'); | |
135 | is(j(sort keys CONST_HASH()) ,$h_expect, 'List: sort keys CONST_HASH()'); | |
136 | is(j(sort keys hash_sub) ,$h_expect, 'List: sort keys hash_sub'); | |
137 | is(j(sort keys hash_sub()) ,$h_expect, 'List: sort keys hash_sub()'); | |
138 | is(j(sort keys $obj->hash) ,$h_expect, 'List: sort keys $obj->hash'); | |
139 | ||
140 | is(j(keys $hash) ,j(values $hash), 'List: keys $hash == values $hash'); | |
141 | is(j(keys $data->{hash}) ,j(values $data->{hash}), 'List: keys $data->{hash} == values $data->{hash}'); | |
142 | is(j(keys CONST_HASH) ,j(values CONST_HASH), 'List: keys CONST_HASH == values CONST_HASH'); | |
143 | is(j(keys CONST_HASH()) ,j(values CONST_HASH()), 'List: keys CONST_HASH() == values CONST_HASH()'); | |
144 | is(j(keys hash_sub) ,j(values hash_sub), 'List: keys hash_sub == values hash_sub'); | |
145 | is(j(keys hash_sub()) ,j(values hash_sub()), 'List: keys hash_sub() == values hash_sub()'); | |
146 | is(j(keys $obj->hash) ,j(values $obj->hash), 'List: keys $obj->hash == values obj->hash'); | |
147 | ||
cba5a3b0 DG |
148 | is(j(keys $array) ,$a_expect, 'List: keys $array'); |
149 | is(j(keys $data->{array}) ,$a_expect, 'List: keys $data->{array}'); | |
150 | is(j(keys CONST_ARRAY) ,$a_expect, 'List: keys CONST_ARRAY'); | |
151 | is(j(keys CONST_ARRAY()) ,$a_expect, 'List: keys CONST_ARRAY()'); | |
152 | is(j(keys array_sub) ,$a_expect, 'List: keys array_sub'); | |
153 | is(j(keys array_sub()) ,$a_expect, 'List: keys array_sub()'); | |
154 | is(j(keys $obj->array) ,$a_expect, 'List: keys $obj->array'); | |
155 | ||
cba5a3b0 | 156 | # Keys -- vivification |
7ac5715b FC |
157 | undef $empty; |
158 | eval { keys $empty->{hash} }; | |
159 | ok(defined $empty, | |
160 | 'Vivify: $empty (after keys $empty->{hash}) is HASHREF'); | |
cba5a3b0 DG |
161 | ok(!defined $empty->{hash} , 'Vivify: $empty->{hash} is undef'); |
162 | ||
d8065907 FC |
163 | # Keys -- lvalue |
164 | $_{foo} = "bar"; | |
165 | keys \%_ = 65; | |
166 | is scalar %_, '1/128', 'keys $hashref as lvalue'; | |
167 | eval 'keys \@_ = 65'; | |
168 | like $@, qr/Can't modify keys on reference in scalar assignment/, | |
169 | 'keys $arrayref as lvalue dies'; | |
170 | ||
cba5a3b0 | 171 | # Keys -- errors |
7ac5715b FC |
172 | $errpat = qr/ |
173 | (?-x:Type of argument to keys on reference must be unblessed hashref or) | |
174 | (?-x: arrayref) | |
175 | /x; | |
176 | ||
177 | eval "keys undef"; | |
178 | ok($@ =~ $errpat, | |
179 | 'Errors: keys undef throws error' | |
180 | ); | |
181 | ||
182 | undef $empty; | |
183 | eval q"keys $empty"; | |
184 | ok($@ =~ $errpat, | |
185 | 'Errors: keys $undef throws error' | |
186 | ); | |
187 | ||
188 | is($empty, undef, 'keys $undef does not vivify $undef'); | |
189 | ||
cba5a3b0 | 190 | eval "keys 3"; |
7ac5715b | 191 | ok($@ =~ qr/Type of arg 1 to keys must be hash/, |
cba5a3b0 DG |
192 | 'Errors: keys CONSTANT throws error' |
193 | ); | |
194 | ||
195 | eval "keys qr/foo/"; | |
7ac5715b | 196 | ok($@ =~ $errpat, |
cba5a3b0 DG |
197 | 'Errors: keys qr/foo/ throws error' |
198 | ); | |
199 | ||
feff7485 | 200 | eval q"keys $hash qw/fo bar/"; |
cba5a3b0 DG |
201 | ok($@ =~ qr/syntax error/, |
202 | 'Errors: keys $hash, @stuff throws error' | |
203 | ) or print "# Got: $@"; | |
204 | ||
205 | # Values -- void | |
206 | ||
207 | values $hash; pass('Void: values $hash;'); | |
208 | values $data->{hash}; pass('Void: values $data->{hash};'); | |
209 | values CONST_HASH; pass('Void: values CONST_HASH;'); | |
210 | values CONST_HASH(); pass('Void: values CONST_HASH();'); | |
211 | values hash_sub(); pass('Void: values hash_sub();'); | |
212 | values hash_sub; pass('Void: values hash_sub;'); | |
213 | values $obj->hash; pass('Void: values $obj->hash;'); | |
214 | values $array; pass('Void: values $array;'); | |
215 | values $data->{array}; pass('Void: values $data->{array};'); | |
216 | values CONST_ARRAY; pass('Void: values CONST_ARRAY;'); | |
217 | values CONST_ARRAY(); pass('Void: values CONST_ARRAY();'); | |
218 | values array_sub; pass('Void: values array_sub;'); | |
219 | values array_sub(); pass('Void: values array_sub();'); | |
220 | values $obj->array; pass('Void: values $obj->array;'); | |
221 | ||
222 | # Values -- scalar | |
223 | ||
224 | is(values $hash ,3, 'Scalar: values $hash'); | |
225 | is(values $data->{hash} ,3, 'Scalar: values $data->{hash}'); | |
226 | is(values CONST_HASH ,3, 'Scalar: values CONST_HASH'); | |
227 | is(values CONST_HASH() ,3, 'Scalar: values CONST_HASH()'); | |
228 | is(values hash_sub ,3, 'Scalar: values hash_sub'); | |
229 | is(values hash_sub() ,3, 'Scalar: values hash_sub()'); | |
230 | is(values $obj->hash ,3, 'Scalar: values $obj->hash'); | |
231 | is(values $array ,3, 'Scalar: values $array'); | |
232 | is(values $data->{array} ,3, 'Scalar: values $data->{array}'); | |
233 | is(values CONST_ARRAY ,3, 'Scalar: values CONST_ARRAY'); | |
234 | is(values CONST_ARRAY() ,3, 'Scalar: values CONST_ARRAY()'); | |
235 | is(values array_sub ,3, 'Scalar: values array_sub'); | |
236 | is(values array_sub() ,3, 'Scalar: values array_sub()'); | |
237 | is(values $obj->array ,3, 'Scalar: values $obj->array'); | |
238 | ||
239 | # Values -- list | |
240 | ||
0e0ab621 | 241 | $h_expect = j(sort values %base_hash); |
cba5a3b0 DG |
242 | $a_expect = j(values @$array); |
243 | ||
0e0ab621 YO |
244 | is(j(sort values $hash) ,$h_expect, 'List: sort values $hash'); |
245 | is(j(sort values $data->{hash}) ,$h_expect, 'List: sort values $data->{hash}'); | |
246 | is(j(sort values CONST_HASH) ,$h_expect, 'List: sort values CONST_HASH'); | |
247 | is(j(sort values CONST_HASH()) ,$h_expect, 'List: sort values CONST_HASH()'); | |
248 | is(j(sort values hash_sub) ,$h_expect, 'List: sort values hash_sub'); | |
249 | is(j(sort values hash_sub()) ,$h_expect, 'List: sort values hash_sub()'); | |
250 | is(j(sort values $obj->hash) ,$h_expect, 'List: sort values $obj->hash'); | |
251 | ||
252 | is(j(values $hash) ,j(keys $hash), 'List: values $hash == keys $hash'); | |
253 | is(j(values $data->{hash}) ,j(keys $data->{hash}), 'List: values $data->{hash} == keys $data->{hash}'); | |
254 | is(j(values CONST_HASH) ,j(keys CONST_HASH), 'List: values CONST_HASH == keys CONST_HASH'); | |
255 | is(j(values CONST_HASH()) ,j(keys CONST_HASH()), 'List: values CONST_HASH() == keys CONST_HASH()'); | |
256 | is(j(values hash_sub) ,j(keys hash_sub), 'List: values hash_sub == keys hash_sub'); | |
257 | is(j(values hash_sub()) ,j(keys hash_sub()), 'List: values hash_sub() == keys hash_sub()'); | |
258 | is(j(values $obj->hash) ,j(keys $obj->hash), 'List: values $obj->hash == keys $obj->hash'); | |
259 | ||
cba5a3b0 DG |
260 | is(j(values $array) ,$a_expect, 'List: values $array'); |
261 | is(j(values $data->{array}) ,$a_expect, 'List: values $data->{array}'); | |
262 | is(j(values CONST_ARRAY) ,$a_expect, 'List: values CONST_ARRAY'); | |
263 | is(j(values CONST_ARRAY()) ,$a_expect, 'List: values CONST_ARRAY()'); | |
264 | is(j(values array_sub) ,$a_expect, 'List: values array_sub'); | |
265 | is(j(values array_sub()) ,$a_expect, 'List: values array_sub()'); | |
266 | is(j(values $obj->array) ,$a_expect, 'List: values $obj->array'); | |
267 | ||
cba5a3b0 | 268 | # Values -- vivification |
7ac5715b FC |
269 | undef $empty; |
270 | eval { values $empty->{hash} }; | |
271 | ok(defined $empty, | |
272 | 'Vivify: $empty (after values $empty->{hash}) is HASHREF'); | |
cba5a3b0 DG |
273 | ok(!defined $empty->{hash} , 'Vivify: $empty->{hash} is undef'); |
274 | ||
275 | # Values -- errors | |
7ac5715b FC |
276 | $errpat = qr/ |
277 | (?-x:Type of argument to values on reference must be unblessed hashref or) | |
278 | (?-x: arrayref) | |
279 | /x; | |
280 | ||
281 | eval "values undef"; | |
282 | ok($@ =~ $errpat, | |
283 | 'Errors: values undef throws error' | |
284 | ); | |
285 | ||
286 | undef $empty; | |
287 | eval q"values $empty"; | |
288 | ok($@ =~ $errpat, | |
289 | 'Errors: values $undef throws error' | |
290 | ); | |
291 | ||
292 | is($empty, undef, 'values $undef does not vivify $undef'); | |
293 | ||
cba5a3b0 | 294 | eval "values 3"; |
7ac5715b | 295 | ok($@ =~ qr/Type of arg 1 to values must be hash/, |
cba5a3b0 DG |
296 | 'Errors: values CONSTANT throws error' |
297 | ); | |
298 | ||
299 | eval "values qr/foo/"; | |
7ac5715b | 300 | ok($@ =~ $errpat, |
cba5a3b0 DG |
301 | 'Errors: values qr/foo/ throws error' |
302 | ); | |
303 | ||
feff7485 | 304 | eval q"values $hash qw/fo bar/"; |
cba5a3b0 DG |
305 | ok($@ =~ qr/syntax error/, |
306 | 'Errors: values $hash, @stuff throws error' | |
307 | ) or print "# Got: $@"; | |
308 | ||
309 | # Each -- void | |
310 | ||
311 | each $hash; pass('Void: each $hash'); | |
312 | each $data->{hash}; pass('Void: each $data->{hash}'); | |
313 | each CONST_HASH; pass('Void: each CONST_HASH'); | |
314 | each CONST_HASH(); pass('Void: each CONST_HASH()'); | |
315 | each hash_sub(); pass('Void: each hash_sub()'); | |
316 | each hash_sub; pass('Void: each hash_sub'); | |
317 | each $obj->hash; pass('Void: each $obj->hash'); | |
318 | each $array; pass('Void: each $array'); | |
319 | each $data->{array}; pass('Void: each $data->{array}'); | |
320 | each CONST_ARRAY; pass('Void: each CONST_ARRAY'); | |
321 | each CONST_ARRAY(); pass('Void: each CONST_ARRAY()'); | |
322 | each array_sub; pass('Void: each array_sub'); | |
323 | each array_sub(); pass('Void: each array_sub()'); | |
324 | each $obj->array; pass('Void: each $obj->array'); | |
325 | ||
326 | # Reset iterators | |
327 | ||
328 | keys $hash; | |
329 | keys $data->{hash}; | |
330 | keys CONST_HASH; | |
331 | keys CONST_HASH(); | |
332 | keys hash_sub(); | |
333 | keys hash_sub; | |
334 | keys $obj->hash; | |
335 | keys $array; | |
336 | keys $data->{array}; | |
337 | keys CONST_ARRAY; | |
338 | keys CONST_ARRAY(); | |
339 | keys array_sub; | |
340 | keys array_sub(); | |
341 | keys $obj->array; | |
342 | ||
343 | # Each -- scalar | |
344 | ||
345 | @tmp=(); while(defined( $k = each $hash)) {push @tmp,$k}; is(j(@tmp),j(keys $hash), 'Scalar: each $hash'); | |
346 | @tmp=(); while(defined( $k = each $data->{hash})){push @tmp,$k}; is(j(@tmp),j(keys $data->{hash}), 'Scalar: each $data->{hash}'); | |
347 | @tmp=(); while(defined( $k = each CONST_HASH)){push @tmp,$k}; is(j(@tmp),j(keys CONST_HASH), 'Scalar: each CONST_HASH'); | |
348 | @tmp=(); while(defined( $k = each CONST_HASH())){push @tmp,$k}; is(j(@tmp),j(keys CONST_HASH()), 'Scalar: each CONST_HASH()'); | |
349 | @tmp=(); while(defined( $k = each hash_sub())){push @tmp,$k}; is(j(@tmp),j(keys hash_sub()), 'Scalar: each hash_sub()'); | |
350 | @tmp=(); while(defined( $k = each hash_sub)){push @tmp,$k}; is(j(@tmp),j(keys hash_sub), 'Scalar: each hash_sub'); | |
351 | @tmp=(); while(defined( $k = each $obj->hash)){push @tmp,$k}; is(j(@tmp),j(keys $obj->hash), 'Scalar: each $obj->hash'); | |
352 | @tmp=(); while(defined( $k = each $array)){push @tmp,$k}; is(j(@tmp),j(keys $array), 'Scalar: each $array'); | |
353 | @tmp=(); while(defined( $k = each $data->{array})){push @tmp,$k}; is(j(@tmp),j(keys $data->{array}), 'Scalar: each $data->{array}'); | |
354 | @tmp=(); while(defined( $k = each CONST_ARRAY)){push @tmp,$k}; is(j(@tmp),j(keys CONST_ARRAY), 'Scalar: each CONST_ARRAY'); | |
355 | @tmp=(); while(defined( $k = each CONST_ARRAY())){push @tmp,$k}; is(j(@tmp),j(keys CONST_ARRAY()), 'Scalar: each CONST_ARRAY()'); | |
356 | @tmp=(); while(defined( $k = each array_sub)){push @tmp,$k}; is(j(@tmp),j(keys array_sub), 'Scalar: each array_sub'); | |
357 | @tmp=(); while(defined( $k = each array_sub())){push @tmp,$k}; is(j(@tmp),j(keys array_sub()), 'Scalar: each array_sub()'); | |
358 | @tmp=(); while(defined( $k = each $obj->array)){push @tmp,$k}; is(j(@tmp),j(keys $obj->array), 'Scalar: each $obj->array'); | |
359 | ||
360 | # Each -- list | |
361 | ||
362 | @tmp=@tmp2=(); while(($k,$v) = each $hash) {push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys $hash, values $hash), 'List: each $hash'); | |
363 | @tmp=@tmp2=(); while(($k,$v) = each $data->{hash}){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys $data->{hash}, values $data->{hash}), 'List: each $data->{hash}'); | |
364 | @tmp=@tmp2=(); while(($k,$v) = each CONST_HASH){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys CONST_HASH, values CONST_HASH), 'List: each CONST_HASH'); | |
365 | @tmp=@tmp2=(); while(($k,$v) = each CONST_HASH()){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys CONST_HASH(), values CONST_HASH()), 'List: each CONST_HASH()'); | |
366 | @tmp=@tmp2=(); while(($k,$v) = each hash_sub()){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys hash_sub(), values hash_sub()), 'List: each hash_sub()'); | |
367 | @tmp=@tmp2=(); while(($k,$v) = each hash_sub){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys hash_sub, values hash_sub), 'List: each hash_sub'); | |
368 | @tmp=@tmp2=(); while(($k,$v) = each $obj->hash){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys $obj->hash, values $obj->hash), 'List: each $obj->hash'); | |
369 | @tmp=@tmp2=(); while(($k,$v) = each $array){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys $array, values $array), 'List: each $array'); | |
370 | @tmp=@tmp2=(); while(($k,$v) = each $data->{array}){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys $data->{array}, values $data->{array}), 'List: each $data->{array}'); | |
371 | @tmp=@tmp2=(); while(($k,$v) = each CONST_ARRAY){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys CONST_ARRAY, values CONST_ARRAY), 'List: each CONST_ARRAY'); | |
372 | @tmp=@tmp2=(); while(($k,$v) = each CONST_ARRAY()){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys CONST_ARRAY(), values CONST_ARRAY()), 'List: each CONST_ARRAY()'); | |
373 | @tmp=@tmp2=(); while(($k,$v) = each array_sub){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys array_sub, values array_sub), 'List: each array_sub'); | |
374 | @tmp=@tmp2=(); while(($k,$v) = each array_sub()){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys array_sub(), values array_sub()), 'List: each array_sub()'); | |
375 | @tmp=@tmp2=(); while(($k,$v) = each $obj->array){push @tmp,$k; push @tmp2,$v}; is(j(@tmp,@tmp2),j(keys $obj->array, values $obj->array), 'List: each $obj->array'); | |
376 | ||
7ac5715b FC |
377 | # Each -- vivification |
378 | undef $empty; | |
379 | eval { each $empty->{hash} }; | |
380 | ok(defined $empty, | |
381 | 'Vivify: $empty (after each $empty->{hash}) is HASHREF'); | |
382 | ok(!defined $empty->{hash} , 'Vivify: $empty->{hash} is undef'); | |
383 | ||
384 | # Each -- errors | |
385 | $errpat = qr/ | |
386 | (?-x:Type of argument to each on reference must be unblessed hashref or) | |
387 | (?-x: arrayref) | |
388 | /x; | |
389 | ||
390 | eval "each undef"; | |
391 | ok($@ =~ $errpat, | |
392 | 'Errors: each undef throws error' | |
393 | ); | |
cba5a3b0 DG |
394 | |
395 | undef $empty; | |
7ac5715b FC |
396 | eval q"each $empty"; |
397 | ok($@ =~ $errpat, | |
398 | 'Errors: each $undef throws error' | |
399 | ); | |
cba5a3b0 | 400 | |
7ac5715b | 401 | is($empty, undef, 'each $undef does not vivify $undef'); |
cba5a3b0 | 402 | |
cba5a3b0 | 403 | eval "each 3"; |
7ac5715b | 404 | ok($@ =~ qr/Type of arg 1 to each must be hash/, |
cba5a3b0 DG |
405 | 'Errors: each CONSTANT throws error' |
406 | ); | |
407 | ||
408 | eval "each qr/foo/"; | |
7ac5715b | 409 | ok($@ =~ $errpat, |
cba5a3b0 DG |
410 | 'Errors: each qr/foo/ throws error' |
411 | ); | |
412 | ||
feff7485 | 413 | eval q"each $hash qw/foo bar/"; |
cba5a3b0 DG |
414 | ok($@ =~ qr/syntax error/, |
415 | 'Errors: each $hash, @stuff throws error' | |
416 | ) or print "# Got: $@"; | |
417 | ||
418 | # Overloaded objects | |
419 | my $over_a = Foo::Overload::Array->new; | |
420 | my $over_h = Foo::Overload::Hash->new; | |
421 | my $over_b = Foo::Overload::Both->new; | |
422 | my $over_h_a = Foo::Overload::HashOnArray->new; | |
423 | my $over_a_h = Foo::Overload::ArrayOnHash->new; | |
424 | ||
cba5a3b0 DG |
425 | { |
426 | my $warn = ''; | |
427 | local $SIG{__WARN__} = sub { $warn = shift }; | |
428 | ||
7ac5715b FC |
429 | $errpat = qr/ |
430 | (?-x:Type of argument to keys on reference must be unblessed hashref or) | |
431 | (?-x: arrayref) | |
432 | /x; | |
433 | ||
434 | eval { keys $over_a }; | |
435 | like($@, $errpat, "Overload: array dereference"); | |
cba5a3b0 DG |
436 | is($warn, '', "no warning issued"); $warn = ''; |
437 | ||
7ac5715b FC |
438 | eval { keys $over_h }; |
439 | like($@, $errpat, "Overload: hash dereference"); | |
cba5a3b0 DG |
440 | is($warn, '', "no warning issued"); $warn = ''; |
441 | ||
7ac5715b FC |
442 | eval { keys $over_b }; |
443 | like($@, $errpat, "Overload: ambiguous dereference (both)"); | |
444 | is($warn, '', "no warning issued"); $warn = ''; | |
cba5a3b0 | 445 | |
7ac5715b FC |
446 | eval { keys $over_h_a }; |
447 | like($@, $errpat, "Overload: ambiguous dereference"); | |
448 | is($warn, '', "no warning issued"); $warn = ''; | |
cba5a3b0 | 449 | |
7ac5715b FC |
450 | eval { keys $over_a_h }; |
451 | like($@, $errpat, "Overload: ambiguous dereference"); | |
452 | is($warn, '', "no warning issued"); $warn = ''; | |
cba5a3b0 | 453 | } |