while (1) { ... next if () ... last } #### LINE: { chomp($row = <$fh>) or last LINE; redo LINE if $key < $min; $done = 1 && return if ($key > $max); } #### sub itter_maker { # return a function that passes back data allowed by the given predicate subroutine my $predicate = shift; #CODE ref my $done = 0; my $fh = IO::File->new($datafile) or die "can't open $datafile: $!\n"; return( sub { return if $done; my (@data,$row,$key); my $found = 0; while( ! $found && ! $done && defined( $row= <$fh> ) ) { chomp($row); ($found, $done) = $predicate->($row, \$key, \@data); } return ($key,\@data) if $found; return; }); }