入出力(5) 特殊ファイルハンドル ARGV

昨日勉強した @ARGV はコマンドライン引数のリストを格納していましたが、ARGV ファイルハンドルはまた別のものです。Perl は同じ名前でも型が違えば全く別の変数として扱うのでしたね。
引数として「ファイル名のリスト」を渡された場合、ARGV はそのファイルの内容を「全て連結した」仮想ファイルハンドルとして動作します。
例えば次のようなコードを書きます。

use strict;
 
while (<ARGV>) {
  chomp;
  print $_, "\n";
}

ARGV ファイルハンドルから一行ずつ取得して改行付きで表示していきます。
これを argv.pl として保存して、引数として「argv.pl」というファイル名を与えると、以下のような実行結果になります。

D:\home\palmo>perl argv.pl argv.pl
use strict;

while (<ARGV>) {
  chomp;
  print $_, "\n";
}

つまり、ARGV ファイルハンドルは argv.pl の内容を表している事になります。
もし、引数として複数のファイル名を渡すと、そのファイルが全て連結されたものが ARGV の内容となります。

D:\home\palmo>perl argv.pl aaa.txt bbb.txt ccc.txt
aaa.txt の内容 1行目
aaa.txt の内容 2行目
aaa.txt の内容 3行目
bbb.txt の内容 1行目
bbb.txt の内容 2行目
bbb.txt の内容 3行目
ccc.txt の内容 1行目
ccc.txt の内容 2行目
ccc.txt の内容 3行目

とても便利。ARGV を使えば手軽にファイルを入力として受け取る事ができますね。


ちなみに、行入力演算子(山カッコ演算子)のファイルハンドルを指定しなかった場合、ARGV が指定された事になります。つまり、以下の2行は等価です。

$s = <ARGV>;
$s = <>;


また、ARGV を使っていて、現在処理しているファイルの名前が知りたくなった場合、特殊変数「$ARGV」にファイル名が入っています。

use strict;
 
while (<>) {
  chomp;
  print $ARGV, ">", $_, "\n";
}
D:\home\palmo>perl argv.pl aaa.txt bbb.txt
aaa.txt>aaa.txt の内容 1行目
aaa.txt>aaa.txt の内容 2行目
aaa.txt>aaa.txt の内容 3行目
bbb.txt>bbb.txt の内容 1行目
bbb.txt>bbb.txt の内容 2行目
bbb.txt>bbb.txt の内容 3行目

これで、3種類の ARGV が登場したわけですが、種類によって役割が全く違っていて面白いです。引数を処理する場合「ARGV」を使う、と覚えておけばいいので覚えやすいですが、コードを読む時にちょっと混乱してしまいそうですね。(^_^;)