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 %h; @h{'a'..'d'} = 1..4; my $factory = hashIteratorFactory( \%h ); my $i1 = $factory->(); my $i2 = $factory->(); print "1:",$i1->(),"\n"; print "1:",$i1->(),"\n"; print "2:",$i2->(),"\n"; print "1:",$i1->(),"\n"; print "1:",$i1->(),"\n"; print "2:",$i2->(),"\n"; print "2:",$i2->(),"\n"; print "1:",$i1->(),"\n"; print "1:",$i1->(),"\n"; print "2:",$i2->(),"\n"; print "2:",$i2->(),"\n"; my $i3 = $factory->(); while( my ($k, $v) = $i3->() ) { print "3:$k$v\n"; } print "2:",$i2->(),"\n"; print "1:",$i1->(),"\n";