---
name: "Hash::StoredIterator"
section: "3pm"
platform: "linux"
package: "libhash-storediterator-perl"
version: "0.008-3+b4"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Hash::StoredIterator"
---

# Hash::StoredIterator(3pm)

Functions for accessing a hashes internal iterator.

## 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 exodist7@gmail.com

## 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.
