9 # This is purposefully simple - hence the O(n) linear searches.
10 package TestIterators {
16 my ($self, $key, $value) = @_;
17 push @{$self->[0]}, $key;
18 push @{$self->[1]}, $value;
23 my ($self, $key) = @_;
25 while ($i < @{$self->[0]}) {
27 if $self->[0][$i] eq $key;
30 die "$key not found in FETCH";
38 # As best I can tell, none of our other tie tests actually use the first
39 # parameter to nextkey. It's actually (a copy of) the previously returned
40 # key. We're not *so* thorough here as to actually hide some state and
41 # cross-check that, but the longhand tests below should effectively validate
44 my ($self, $key) = @_;
46 while ($i < @{$self->[0]}) {
47 return $self->[0][$i + 1]
48 if $self->[0][$i] eq $key;
51 die "$key not found in NEXTKEY";
57 tie %h, 'TestIterators';
62 is($h{beer}, "foamy", "found first key");
63 is($h{perl}, "rules", "found second key");
67 }, undef, "missing key was not found");
68 like($@, qr/\Adecaf not found in FETCH/, "with the correct error");
70 is(each %h, 'beer', "first iterator");
71 is(each %h, 'perl', "second iterator");
72 is(each %h, undef, "third iterator is undef");
80 lolrus => "I HAS A BUCKET",
83 my @want = sort keys %h;
94 # This is a sanity test:
95 is("@have", "@want", "get all keys from a loop");
102 ok(defined $k1, "Got a key");
114 is(scalar @have, 1, "just 1 key from the loop this time");
115 isnt($k1, $have[0], "two different keys");
117 @have = sort @have, $k1;
118 is("@have", "@want", "get all keys just once");
120 # And this is the real test.
122 # Previously pp_tie would mangle the hash iterator state - it would reset
123 # EITER but not RITER, meaning that if the iterator happened to be partway
124 # down a chain of entries, the rest of that chain would be skipped, but if
125 # the iterator's next position was the start of a (new) chain, nothing would
127 # We don't have space to store the complete older iterator state (and really
128 # nothing should be relying on it), so it seems better to correctly reset
129 # the iterator (every time), than leave it in a mess just occasionally.
136 ok(defined $k1, "Got a key");
138 tie %h, 'Tie::StdHash';
149 is(scalar @have, 2, "2 keys from the loop this time");
150 is("@have", "@want", "tie/untie resets the hash iterator");
158 use parent -norequire, 'Tie::StdHash';
161 return $_[0]->SUPER::FETCH($_[1]);
167 tie %tied, "Tie::Count";
168 %tied = qw(perl rules beer foamy);
170 if ($a[0] eq 'beer') {
171 is("@a", "beer foamy perl rules", "tied hash in list context");
173 is("@a", "perl rules beer foamy", "tied hash in list context");
175 is($count, 2, "two FETCHes for tied hash in list context");
181 is("@a", "beer perl", "tied hash keys in list context");
182 is($count, 0, "no FETCHes for tied hash keys in list context");
188 is("@a", "foamy rules", "tied hash values in list context");
189 is($count, 2, "two FETCHes for tied hash values in list context");
193 # tie/untie on a hash resets the iterator
195 # This is not intended as a test of *correctness*. This behaviour is
196 # observable by code on CPAN, so potentially some of it will inadvertently
197 # be relying on it (and likely not in any regression test). Hence this
198 # "test" here is intended as a way to alert us if any core code change has
199 # the side effect of alerting this observable behaviour.
201 my @keys = qw(bactrianus dromedarius ferus);
207 push @got, scalar each %Camelus;
208 push @got, scalar each %Camelus;
209 push @got, scalar each %Camelus;
210 is(scalar each %Camelus, undef, 'Fourth each returned undef');
211 is(join(' ', sort @got), "@keys", 'The correct three keys');
216 push @got, scalar each %Camelus;
218 # This resets the hash iterator:
219 tie %Camelus, 'Tie::StdHash';
220 my @all = keys %Camelus;
221 is(scalar @all, 0, 'Zero keys when tied');
224 push @got, scalar each %Camelus;
225 push @got, scalar each %Camelus;
226 my $fourth = scalar each %Camelus;
227 isnt($fourth, undef, 'Fourth each did not return undef');
229 is(scalar each %Camelus, undef, 'Fifth each returned undef');
232 is(join(' ', sort keys %have), "@keys", 'Still the correct three keys');