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

I use Perl for one-liners all the time -- nothing can top it there.

But when the task at hand grows just slightly bigger, to the point where I know I'll need to pass filehandles to/from my own functions, my skin starts to literally itch because of how bad the filehandle situation is.

It's not plain "open F, ..." any more... Is it "*F"? Is it "\*F"? Are those the same thing? (What the hell is a "typeglob"?) Wait, can't I just use "open my $f" and everything works the way it obviously should? Well, kinda, unless you want to be able to store an existing filehandle like STDIN in there, then you have to do something different again... Do I need IO::Handle instead? (Why does that need to exist...?)



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=;




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

Search: