Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Plain perl:

  open my $fh, '<', $filename or die "Couldn't open ${filename}: $!";
Nicer:

  use File::Open qw(fopen);
  ...
  my $fh = fopen $filename;
(and File::Open is simple pure perl code so if I need to distribute the script to random machines I throw App::FatPacker at it to produce a bundled version)


"my $fh" works fine if you only want to work with files you open() yourself, but what if you want to write a function that, based on some test, returns either that or the preexisting STDOUT filehandle?


    sub foo {
      if (whatever) {
        open my $fh, ...;
        return $fh;
      } else {
        return \*STDOUT;
      }
    }
will do the job.


Thanks. I feel certain that I tried exactly this a long time ago, and it didn't work as expected, but I may be misremembering. I'll give this a shot the next time I'm in front of a keyboard -- if it works, it will be nothing short of healing.


Slight oddities converting it into a one-liner but here's a copy and paste from a shell session running in my local WSL slice:

  demeisen=; perl -e 'my $in_fh = (defined $ARGV[0] and $ARGV[0] ne "-") ? do { open my $fh, "<", $ARGV[0] or die "Failed to open $ARGV[0]: $!"; $fh } : \*STDIN; print "Line: ".<$in_fh>;'
  HELLO
  Line: HELLO
  demeisen=; perl -e 'my $in_fh = (defined $ARGV[0] and $ARGV[0] ne "-") ? do { open my $fh, "<", $ARGV[0] or die "Failed to open $ARGV[0]: $!"; $fh } : \*STDIN; print "Line: ".<$in_fh>;' -
  HELLO
  Line: HELLO
  demeisen=; echo 'HI' >tmp/hi  
  demeisen=; perl -e 'my $in_fh = (defined $ARGV[0] and $ARGV[0] ne "-") ? do { open my $fh, "<", $ARGV[0] or die "Failed to open $ARGV[0]: $!"; $fh } : \*STDIN; print "Line: ".<$in_fh>;' tmp/hi
  Line: HI
  demeisen=;




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: