Hash::StoredIterator(3pm) | User Contributed Perl Documentation | Hash::StoredIterator(3pm) |
Hash::StoredIterator - Functions for accessing a hashes internal iterator.
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().
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 );
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.
Note: See caveats.
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.
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.
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.
These have been deprecated because they were terrible names. eich was also deprecated because it was unnatural to use.
Chad Granum exodist7@gmail.com
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.
2024-10-15 | perl v5.40.0 |