my @indexes = qw (3 0 4 5 6 7); open INDATA,"< my.dat" or die "my.dat: $!"; sub read_row { my $row = ; return unless defined($row); return (split(/\s+/,$row))[@indexes]; } sub get_indexes { return @indexes; } #### use IO::File; sub process_each_file_line { my( $filename, $preprocess_cb, $process_cb ) = @_; my $fh = IO::File->new( "< $filename" ) or die "open $filename for reading: $!"; while ( <$fh> ) { $process_cb->( $preprocess_cb->() ); } } sub process { my( $filename, @indexes ) = @_; my @result; process_each_file_line( $filename, sub { (split)[ @indexes ] }, sub { local $" = ','; push @result, "test : @_\n"; } ); return @result; } # call the function: print process( "my.dat", qw( 3 0 4 5 6 7 ) ); #### use IO::File; sub process_each_file_line { my( $filename, $preprocess_cb, $process_cb ) = @_; my $fh = IO::File->new( "< $filename" ) or die "open $filename for reading: $!"; while ( <$fh> ) { $process_cb->( $preprocess_cb->() ); } } sub make_file_processor { my( $filename, @indexes ) = @_; return sub { # make a closure which takes no args. my @result; process_each_file_line( $filename, sub { (split)[ @indexes ] }, sub { local $" = ','; push @result, "test : @_\n"; } ); return @result; } } # create the processor for the given input params: my $processor = make_file_processor( "my.dat", qw( 3 0 4 5 6 7 ) ); # later on, call the closure: print $processor->();