__DATA__をmod_perlやらFCGIなどで使ってハマる人が俺以外にも居る件

自分と同様にはまっている人がいるので、書いておくといつか誰かの役に立つかもしれないというエントリーです。

スクリプト

#!/usr/bin/perl
use strict;
use warnings;

my $data = <<END_OF_DATA;
test1
test2
test3
END_OF_DATA

### ファイルハンドルopen
open my $fh, '<', \$data;

### 現在のファイル位置を調べる
warn tell $fh;

### read
my @array1 = <$fh>;

### 読み取り開始位置が最後に移動している事を確認。 ( 文字数 + 改行 ) * 3 = 18byte
warn tell $fh;

### ファイルの終端まで読み取り位置が進んでいるのでその続きを読んでも何もない
my @array2 = <$fh>;
warn tell $fh;

### close命令
close $fh;

warn @array1;
warn @array2;

実行結果

:!perl %
0 at script/file_handle.pl line 16.
18 at script/file_handle.pl line 22, <$fh> line 3.
18 at script/file_handle.pl line 26, <$fh> line 3.
test1
test2
test3
Warning: something's wrong at script/file_handle.pl line 32.

自分がPerlを学び始めたころは、ファイルを開く、読む、閉じる、という処理をおまじないのように暗記して覚えました。

結果、この「開く、読む、閉じる」という行為を理解せず、ぼんやりと覚えてしまっている事が原因だと思います。

mod_perlFCGIは一度起動したプロセスを終了させないで使用する仕組みです。したがってcloseが自動的には呼び出されいない、という事を理解すればいいかと*1

昔自分もCatalystの組み込みサーバーでは動いていた処理がFCGIで起動したとたんに上手くいかなかった事がありました。もし同じ失敗をした方がいらっしゃって、問題解決に時間をかけずに済むようになればうれしいのですが。

*1:そういえば__DATA__をcloseする処理を見たことが無い、それもFILEHANDLEということを忘れる原因か?