Perl Perl_4
Perl ディレクトリ操作 05 glob ダイヤモンド演算子 注意点 (0x228)

目次 - Perl Index
Theme
Perl について、復習を兼ねて断片的な情報を掲載して行く連載その 0x228 回。
Perl で ディレクトリからファイル名を取得する演算子「 glob 」の代わりにダイヤモンド演算子 ( ヌルファイルハンドル )「 < > 」を利用する場合の注意点を確認する。
グロブなのかファイルハンドルなのか
(0x4a) 等で確認した通り、「 <> 」は「 グロブ 」だけでなく「 ファイルハンドル 」から、当該ファイルの行を読み込む際にも利用します。
ですから、Perl は「 <> 」に与えられた文字列が「 グロブ 」なのか「 ファイルハンドル 」なのかを判別しなければいけません。
この判別は、プログラムのコンパイル時に行われるため、変数の中身とは無関係に決定されるといいますが、具体的にどの様に判別しているのかを確認します。
判別の例
「 初めての Perl 第 6 版」( 13.2 グロブのもう 1 つの書き方 ) では、次の例が紹介されています。
my $files = <FRED/*>; # グロブ
my $files = <FRED>; # ファイルハンドル
my $files = <$fred>; # ファイルハンドル
my $name = 'FRED';
my $files = <$name/*>; # グロブ
例外として、文字列が単純なスカラ変数のみで、「 /* 」などのディレクトリやファイルを表すメタキャラクタが含まれない場合、それは「 間接ファイルハンドル 」( indirect filehandle ) として判別されるとのことです。
間接ファイルハンドルとして判別する
前項の最後の例と似ていますが、次の例は「 グロブ 」ではなく「 間接ファイルハンドル 」として判別されます。
my $name = 'FRED';
my $files = <$name> # 間接ファイルハンドル
このスカラ変数「 $name 」は、ファイルハンドルの識別子「 FRED 」の間接ファイルハンドルと判別されます。これは、内部的には、関数「 readline() 」を利用した「 readline($name) 」の処理になるそうです。
通常、間接ファイルハンドルは、(0x4d) で確認した様に、演算子「 open 」で次のように利用すると理解しています。
open my $fh, '<', 'file_in', or die "Message: $!";
ここでは、スカラ変数「 $fh 」が間接ファイルハンドルになります。これを次のように利用すると、それは間接ファイルハンドルから「 <> 」を利用して行を読み込んでいることになる訳ですね。
# 例えば while で処理をする
while (<$fh>) {
chomp;
print "$_\n";
}
変数展開を含む場合は「 glob 」を利用する
ここまでで確認した通り、ダイヤモンド演算子 ( ヌルファイルハンドル ) 「 <> 」で変数展開を行う場合は、それが、単純な文字列なのか、それとも間接ファイルハンドルなのかというちょっとした混乱を招くおそれがあります。
ですから、perlop - perldoc.jp の次の例の様に、通常は演算子「 glob 」の利用が推奨されています。
@files = glob("$dir/*.[ch]");
@files = glob($files[$i]);
0x228 -> 0x229 へ
次回は、「 ディレクトリハンドル 」を確認します。
参考情報は書籍「 初めての Perl 第 6 版 」を中心に perldoc, Wikipedia および各 Web サイト。それと詳しい先輩。
目次 - Perl Index
Perl mp2 翻訳 Web コンテンツ圧縮の FAQ (d228)
Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227)
Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226)
Perl mp2 翻訳 テンプレートシステムの選択 (d225)
Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224)
Perl mp2 翻訳 チュートリアル (d223)
Perl mp2 翻訳 既知のブラウザのバグの回避策をいくつか (d227)
Perl mp2 翻訳 Perl と Apache でのキュートなトリック (d226)
Perl mp2 翻訳 テンプレートシステムの選択 (d225)
Perl mp2 翻訳 大規模 E コマースサイトの構築 (d224)
Perl mp2 翻訳 チュートリアル (d223)