-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathREADME
189 lines (127 loc) · 5.44 KB
/
README
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
NAME
Hash::StoredIterator - Functions for accessing a hashes internal
iterator.
DESCRIPTION
In perl all hashes have an internal iterator. This iterator is used by
the each() function, as well as by keys() and values(). Because these
all share use of the same iterator, they tend to interact badly with
each other when nested.
Hash::StoredIterator gives you access to get, set, and init the
iterator inside a hash. This allows you to store the current iterator,
use each/keys/values/etc, and then restore the iterator, this helps you
to ensure you do not interact badly with other users of the iterator.
Along with low-level get/set/init functions, there are also 2
variations of each() which let you act upon each key/value pair in a
safer way than vanilla each()
This module can also export new implementations of keys() and values()
which stash and restore the iterator so that they are safe to use
within each().
SYNOPSIS
use Hash::StoredIterator qw{
hmap
hkeys
hvalues
iterator
hash_get_iterator
hash_set_iterator
hash_init_iterator
};
my %hash = map { $_ => uc( $_ )} 'a' .. 'z';
my @keys = hkeys %hash;
my @values = hvalues %hash;
Each section below is functionally identical.
my $iterator = iterator %hash;
while( my ( $k, $v ) = $i->() ) {
print "$k: $value\n";
}
hmap { print "$a: $b\n" } %hash;
hamp { print "$_: $b\n" } %hash;
hmap {
my ( $key, $val ) = @_;
print "$key: $val\n";
} %hash;
It is safe to nest calls to hmap(), iterator(), hkeys(), and hvalues()
hmap {
my ( $key, $val ) = @_;
print "$key: $val\n";
my @keys = hkeys( %hash );
} %hash;
hmap() and iterator() will also properly handle calls to CORE::each,
CORE::keys, and Core::values nested within them.
hmap {
my ( $key, $val ) = @_;
print "$key: $val\n";
# No infinite loop!
my @keys = keys %hash;
} %hash;
Low Level:
hash_init_iterator( \%hash );
my $iter = hash_get_iterator( \%hash );
# NOTE: Never manually specify an $iter value, ALWAYS use a value from
# hash_get_iterator.
hash_set_iterator( \%hash, $iter );
EXPORTS
my $i = iterator %hash
Get an iterator that can be used to retrieve key/value pairs.
my $i = iterator %hash;
while( my ($k, $v) = $i->() ) {
...
}
The iterator is a coderef, so you call it like this: $i-()>. You can
also use the sub anywhere you would use any other coderef.
hmap( \&callback, %hash )
hmap { ... } %hash
Iterate each key/pair calling $callback-( $key, $value )> for each
set. In addition $a and $_ are set to the key, and $b is set to the
value. This is done primarily for convenience of matching against the
key, and short callbacks that will be cluttered by parsing @_ noise.
Note: See caveats.
my @keys = hkeys( %hash )
Same as the builtin keys(), except it stores and restores the
iterator.
Note: Overriding the builtin keys(), even locally, causes strange
interactions with other builtins. When trying to export hkeys as
keys, a call to sort keys %hash would cause undef to be passed into
keys() as the first and only argument.
my @values = hvalues( %hash )
Same as the builtin values(), except it stores and restores the
iterator.
Note: Overriding the builtin values(), even locally, causes strange
interactions with other builtins. When trying to export hvalues as
values, a call to sort values %hash would cause undef to be passed
into values() as the first and only argument.
my $i = hash_get_iterator( \%hash )
Get the current iterator value.
hash_set_iterator( \%hash, $i )
Set the iterator value.
Note: Only ever set this to the value retrieved by
hash_get_iterator(), setting the iterator in any other way is
untested, and may result in undefined behavior.
hash_init_iterator( \%hash )
Initialize or reset the hash iterator.
DEPRECATED
These have been deprecated because they were terrible names. eich was
also deprecated because it was unnatural to use.
eich
use iterator() instead
eech
use hmap instead
CAVEATS
Modification of hash during iteration
Just like with the builtin each() modifying the hash between calls to
each is not recommended and can result in undefined behavior. The
builtin each() does allow for deleting the iterations key, however
that is NOT supported by this library.
sort() edge case
For some reason [sort hkeys %hash] and [sort hkeys(%hash)] both
result in a list that has all the keys and values (and strangely not
in sorted order). However [sort(hkeys(%hash))] works fine.
AUTHORS
Chad Granum [email protected]
COPYRIGHT
Copyright (C) 2013 Chad Granum
Hash-StoredIterator is free software; Standard perl licence.
Hash-StoredIterator is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license
for more details.