To iterate over a hash in Perl, you can fetch up front a list of keys()
(or values()) and use a for loop. But if that's not an option, your only
other choice is each(), which uses an implicit internal iterator stored
in the hash itself. This is brittle: If during the iteration you call a
function which also uses each() on the same hash (or keys() or values()
or just the hash in list context), things break.
That's why I'd like for Perl to have external hash iterators.
Desired properties:
* A hash iterator is exposed to Perl code as some kind of scalar value.
* You can obtain an iterator for any hash.
* You can obtain the current key/value pair from an iterator and
advance it to the next entry, if any, or detect the end of the hash.
* A hash can have any number of concurrent iterators.
* External hash iterators don't interact with each other nor with the
internal iterator.
* Modifying the structure of a hash invalidates all of its iterators,
but that doesn't have to be an observable state. I'm fine if it
means an iterator might skip or revisit some entries.
For example, it might look like this:
my $it = iterator(\%ENV);
while (my ($key, $value) = $it->()) {
say "$key=$value";
}
Here the iterator is exposed as a code reference that returns either the
next key/value pair or the empty list each time it is invoked.
How feasible would it be to implement such a thing?
(or values()) and use a for loop. But if that's not an option, your only
other choice is each(), which uses an implicit internal iterator stored
in the hash itself. This is brittle: If during the iteration you call a
function which also uses each() on the same hash (or keys() or values()
or just the hash in list context), things break.
That's why I'd like for Perl to have external hash iterators.
Desired properties:
* A hash iterator is exposed to Perl code as some kind of scalar value.
* You can obtain an iterator for any hash.
* You can obtain the current key/value pair from an iterator and
advance it to the next entry, if any, or detect the end of the hash.
* A hash can have any number of concurrent iterators.
* External hash iterators don't interact with each other nor with the
internal iterator.
* Modifying the structure of a hash invalidates all of its iterators,
but that doesn't have to be an observable state. I'm fine if it
means an iterator might skip or revisit some entries.
For example, it might look like this:
my $it = iterator(\%ENV);
while (my ($key, $value) = $it->()) {
say "$key=$value";
}
Here the iterator is exposed as a code reference that returns either the
next key/value pair or the empty list each time it is invoked.
How feasible would it be to implement such a thing?