sub your_function { my ( $string, $in_fh, $out ) = @_; local *OUTFH; # opens $out if it's a filename # dupes $out if it's a filehandle open OUTFH, ">$out" or die "$out: $!\n"; # do whatever with $in_fh and $string while( <$in_fh> ) { /$string/o and print OUTFH "$string: $_" } # close OUTFH: either we opened it or we duped it # Either way we don't need it any more. close OUTFH; } #### your_function( $string, \*INPUT, '/tmp/somefile' ); #### # print to STDOUT instead of to disk your_function( $string, \*INPUT, "&STDOUT" ); # print to already-opened filehandle open OUTPUT, '> /tmp/somefile' or die "/tmp/somefile: $!\n"; your_function( $string, \*INPUT, "&OUTPUT" ); #### open OUTFH, ">$out" or die "$out: $!\n"; #### # wrong: given, eg, &STDOUT, creates a file named '&STDOUT' open OUTFH, "> $out" or die "$out: $!\n"; # wrong: also creates, eg, '&STDOUT' open OUTFH, '>', $out or die "$out: $!\n";