今どき(今頃?)のperlのopen事情
いわずと知れたdankogai氏のちょっと前の記事ですが。
はてブでも複数指摘があった通り、ベアワードのファイルハンドルの使用は、STDIN, STDOUT, STDERR, ARGVなど、あらかじめ用意されているものに限り、あとはopen my $fh, ...やopendir my $dh ...を使いましょう。
あと、openが失敗した場合に備えましょう。
before:open IN, '< _lsres_';after:
open my $fh, '<', '_lsres_' or die $!;または
my $filename = '_lsres_'; open my $fh, '<', $filename or die "filename : $!";<<
うわー、こんな書き方できるのか。さすがにopenでファイルハンドルを生で使うのは鬱陶しかったのでずっとFileHandleモジュール使ってたけどこれは時代遅れなのね。
shellに依存しないようにするためには、以下のようにします。
open my $pipe, '-|' or exec 'ls', '-la', $sdir or die $!;このあたりのことは、perldoc perlsecを参照のこと。
これ見てふと思ったんだけど、
cat hogehoge.txt | sort | uniq
みたいにパイプを連続するにはどうすればいいのやら?
調べてみたら、perldoc perlfuncのopenの項目あたりにヒントが。
If you open a pipe on the command '-', i.e., either '|-' or '-|' with 2-arguments (or 1-argument) form of open(), then there is an implicit fork done, and the return value of open is the pid of the child within the parent process, and 0 within the child process. (Use defined($pid) to determine whether the open was successful.)
…なるほど。暗黙的にforkされてんのか。
だとしたら…
#!/usr/bin/perl use strict; use warnings; if (my $pid = open my $pipe, '-|') { while(<$pipe>) { print '[parent]: ' . $_; } close $pipe; } else { open my $pipec, '|-' or exec 'sort', '-nk1' or die $!; print $pipec "70 banana\n"; print $pipec "200 melon\n"; print $pipec "50 apple\n"; print $pipec "120 orange\n"; close $pipec; close $pipe; exit; }
こんな感じで…
[parent]: 50 apple [parent]: 70 banana [parent]: 120 orange [parent]: 200 melon
おー動いた!
しかし直感的じゃねーな・・他にいい書き方ないのかな?