sub get_closure { my ($filename) = @_; open my $ifh, "<", $filename or die $!; return sub { # subroutine that returns one record per call } } # and then: my $getNextRecord = get_closure($filename); while ( my $record = $getNextRecord->() ){ # do something with $record }