.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Hash::StoredIterator 3pm" .TH Hash::StoredIterator 3pm "2014-08-15" "perl v5.20.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Hash::StoredIterator \- Functions for accessing a hashes internal iterator. .SH "DESCRIPTION" .IX Header "DESCRIPTION" In perl all hashes have an internal iterator. This iterator is used by the \&\f(CW\*(C`each()\*(C'\fR function, as well as by \f(CW\*(C`keys()\*(C'\fR and \f(CW\*(C`values()\*(C'\fR. Because these all share use of the same iterator, they tend to interact badly with eachother when nested. .PP 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. .PP Along with low-level get/set/init functions, there are also 2 variations of \&\f(CW\*(C`each()\*(C'\fR which let you act upon each key/value pair in a safer way than vanilla \f(CW\*(C`each()\*(C'\fR .PP This module can also export new implementations of \f(CW\*(C`keys()\*(C'\fR and \f(CW\*(C`values()\*(C'\fR which stash and restore the iterator so that they are safe to use within \&\f(CW\*(C`each()\*(C'\fR. .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 9 \& use Hash::StoredIterator qw{ \& hmap \& hkeys \& hvalues \& iterator \& hash_get_iterator \& hash_set_iterator \& hash_init_iterator \& }; \& \& my %hash = map { $_ => uc( $_ )} \*(Aqa\*(Aq .. \*(Aqz\*(Aq; \& \& my @keys = hkeys %hash; \& my @values = hvalues %hash; .Ve .PP Each section below is functionally identical. .PP .Vb 4 \& my $iterator = iterator %hash; \& while( my ( $k, $v ) = $i\->() ) { \& print "$k: $value\en"; \& } \& \& hmap { print "$a: $b\en" } %hash; \& \& hamp { print "$_: $b\en" } %hash; \& \& hmap { \& my ( $key, $val ) = @_; \& print "$key: $val\en"; \& } %hash; .Ve .PP It is safe to nest calls to \f(CW\*(C`hmap()\*(C'\fR, \f(CW\*(C`iterator()\*(C'\fR, \f(CW\*(C`hkeys()\*(C'\fR, and \f(CW\*(C`hvalues()\*(C'\fR .PP .Vb 5 \& hmap { \& my ( $key, $val ) = @_; \& print "$key: $val\en"; \& my @keys = hkeys( %hash ); \& } %hash; .Ve .PP \&\f(CW\*(C`hmap()\*(C'\fR and \f(CW\*(C`iterator()\*(C'\fR will also properly handle calls to \f(CW\*(C`CORE::each\*(C'\fR, \&\f(CW\*(C`CORE::keys\*(C'\fR, and \f(CW\*(C`Core::values\*(C'\fR nested within them. .PP .Vb 3 \& hmap { \& my ( $key, $val ) = @_; \& print "$key: $val\en"; \& \& # No infinite loop! \& my @keys = keys %hash; \& } %hash; .Ve .PP Low Level: .PP .Vb 5 \& hash_init_iterator( \e%hash ); \& my $iter = hash_get_iterator( \e%hash ); \& # NOTE: Never manually specify an $iter value, ALWAYS use a value from \& # hash_get_iterator. \& hash_set_iterator( \e%hash, $iter ); .Ve .SH "EXPORTS" .IX Header "EXPORTS" .ie n .IP "my $i = iterator %hash" 4 .el .IP "my \f(CW$i\fR = iterator \f(CW%hash\fR" 4 .IX Item "my $i = iterator %hash" Get an iterator that can be used to retrieve key/value pairs. .Sp .Vb 4 \& my $i = iterator %hash; \& while( my ($k, $v) = $i\->() ) { \& ... \& } .Ve .Sp The iterator is a coderef, so you call it like this: \f(CW\*(C`$i\-\*(C'\fR()>. You can also use the sub anywhere you would use any other coderef. .ie n .IP "hmap( \e&callback, %hash )" 4 .el .IP "hmap( \e&callback, \f(CW%hash\fR )" 4 .IX Item "hmap( &callback, %hash )" .PD 0 .ie n .IP "hmap { ... } %hash" 4 .el .IP "hmap { ... } \f(CW%hash\fR" 4 .IX Item "hmap { ... } %hash" .PD Iterate each key/pair calling \f(CW\*(C`$callback\-\*(C'\fR( \f(CW$key\fR, \f(CW$value\fR )> for each set. In addition \f(CW$a\fR and \f(CW$_\fR are set to the key, and \f(CW$b\fR 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 \f(CW@_\fR noise. .Sp \&\fBNote:\fR See caveats. .ie n .IP "my @keys = hkeys( %hash )" 4 .el .IP "my \f(CW@keys\fR = hkeys( \f(CW%hash\fR )" 4 .IX Item "my @keys = hkeys( %hash )" Same as the builtin \f(CW\*(C`keys()\*(C'\fR, except it stores and restores the iterator. .Sp \&\fBNote:\fR Overriding the builtin \fIkeys()\fR, even locally, causes stange interactions with other builtins. When trying to export hkeys as keys, a call to \f(CW\*(C`sort keys %hash\*(C'\fR would cause undef to be passed into \fIkeys()\fR as the first and only argument. .ie n .IP "my @values = hvalues( %hash )" 4 .el .IP "my \f(CW@values\fR = hvalues( \f(CW%hash\fR )" 4 .IX Item "my @values = hvalues( %hash )" Same as the builtin \f(CW\*(C`values()\*(C'\fR, except it stores and restores the iterator. .Sp \&\fBNote:\fR Overriding the builtin \fIvalues()\fR, even locally, causes stange interactions with other builtins. When trying to export hvalues as values, a call to \f(CW\*(C`sort values %hash\*(C'\fR would cause undef to be passed into \fIvalues()\fR as the first and only argument. .ie n .IP "my $i = hash_get_iterator( \e%hash )" 4 .el .IP "my \f(CW$i\fR = hash_get_iterator( \e%hash )" 4 .IX Item "my $i = hash_get_iterator( %hash )" Get the current iterator value. .ie n .IP "hash_set_iterator( \e%hash, $i )" 4 .el .IP "hash_set_iterator( \e%hash, \f(CW$i\fR )" 4 .IX Item "hash_set_iterator( %hash, $i )" Set the iterator value. .Sp \&\fBNote:\fR Only ever set this to the value retrieved by \f(CW\*(C`hash_get_iterator()\*(C'\fR, setting the iterator in any other way is untested, and may result in undefined behavior. .IP "hash_init_iterator( \e%hash )" 4 .IX Item "hash_init_iterator( %hash )" Initialize or reset the hash iterator. .SH "DEPRECATED" .IX Header "DEPRECATED" These have been deprecated because they were terrible names. eich was also deprecated because it was unnatural to use. .IP "eich" 4 .IX Item "eich" use \fIiterator()\fR instead .IP "eech" 4 .IX Item "eech" use hmap instead .SH "CAVEATS" .IX Header "CAVEATS" .IP "Modification of hash during iteration" 4 .IX Item "Modification of hash during iteration" Just like with the builtin \f(CW\*(C`each()\*(C'\fR modifying the hash between calls to each is not recommended and can result in undefined behavior. The builtin \f(CW\*(C`each()\*(C'\fR does allow for deleting the iterations key, however that is \fB\s-1NOT\s0\fR supported by this library. .IP "\fIsort()\fR edge case" 4 .IX Item "sort() edge case" For some reason \f(CW\*(C`[sort hkeys %hash]\*(C'\fR and \f(CW\*(C`[sort hkeys(%hash)]\*(C'\fR both result in a list that has all the keys and values (and strangly not in sorted order). However \f(CW\*(C`[sort(hkeys(%hash))]\*(C'\fR works fine. .SH "AUTHORS" .IX Header "AUTHORS" Chad Granum exodist7@gmail.com .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright (C) 2013 Chad Granum .PP Hash-StoredIterator is free software; Standard perl licence. .PP Hash-StoredIterator is distributed in the hope that it will be useful, but \&\s-1WITHOUT ANY WARRANTY\s0; without even the implied warranty of \s-1MERCHANTABILITY\s0 or \&\s-1FITNESS FOR A PARTICULAR PURPOSE. \s0 See the license for more details.