http://www.perlmonks.org?node_id=1041811


in reply to Re^2: Indepedent lazy iterators for the same hash?
in thread Indepedent lazy iterators for the same hash?

I have added another layer of bookkeeping to make it simpler to use assuming that something like HASH(0x7c2300) is a unique identifier for a hash and does not change during runtime.

use strict; use warnings; sub hashIteratorFactory { my $h = shift; my @both; my $exhausted = 0; return sub { my $i = 0; return sub { my ($k, $v); if( !defined $both[$i] ) { if( !$exhausted and (( $k, $v ) = each %$h) ) { push @both, [ $k, $v ]; } else { $exhausted = 1; $i = 0; return wantarray() ? () : undef(); } } else { ( $k, $v ) = @{$both[$i]}; } $i++; return wantarray() ? ( $k, $v ) : $k; } } } my %hashIteratorStore; sub hashIterator { my $h = shift; die "Not a hash reference!" unless ref $h eq 'HASH'; $hashIteratorStore{$h} //= hashIteratorFactory($h); return $hashIteratorStore{$h}->(); } my %h; @h{'a'..'d'} = 1..4; print \%h,"\n"; my %h2; @h2{'e'..'i'} = 5..8; my $i1 = hashIterator( \%h ); my $i2 = hashIterator( \%h ); print "1:",$i1->(),"\n"; print "1:",$i1->(),"\n"; print "2:",$i2->(),"\n"; print "1:",$i1->(),"\n"; print "1:",$i1->(),"\n"; my $i4 = hashIterator( \%h2 ); print "2:",$i2->(),"\n"; print "2:",$i2->(),"\n"; print "1:",$i1->(),"\n"; print "4:",$i4->(),"\n"; print "4:",$i4->(),"\n"; print "1:",$i1->(),"\n"; print "2:",$i2->(),"\n"; print "2:",$i2->(),"\n"; my $i3 = hashIterator( \%h ); while( my ($k, $v) = $i3->() ) { print "3:$k$v\n"; } print "2:",$i2->(),"\n"; print "1:",$i1->(),"\n";

This is really only a starting point as it is really read-only. If the hash is changed somewhere inbetween, the cached keys and values will be unmodified. So more work is required.

Replies are listed 'Best First'.
Re^4: Indepedent lazy iterators for the same hash?
by LanX (Saint) on Jul 01, 2013 at 10:55 UTC
    Interesting, but the main problem remains that each has global effects.

    So anyone else using each, keys or values on the same hash will reset (and sabotage) the internal iterator.

    After all storing all keys in an array is still the only reliable option. :(

    Cheers Rolf

    ( addicted to the Perl Programming Language)