具体的には読み込み自体は成功するのですが、以下のような一般的(と思うんですが)複数行あるはずのデータが一行になってforeach が一回しか回らないという現象です。
if ( !open( FH, $filename ) ) {エラー処理}
my @array = <FH>;close(FH);
foreach my $line(@array){
ほにゃらら。
}
厄介なのは起きるときと起きない時があるところです。
成功するときは問題なく取れるが失敗すると数百行あっても一行として読み込まれてしまいます。
現象が出始めるとApacheのリスタートで直ります。
違うサーバで試しに移動してみると再現しません。
環境
Red Hat Enterprise Linux ES release 4
Apache2.0.52
Perl v5.8.5
mod_perl 1.99
use strict、warningsは問題があるプログラムではつけいるしエラー、警告は出ていません。
ただしつけてないプログラムが同じサーバに同居しています。
たぶんメモリ関係だと思うのですが。
なにか関連するモジュールでの不具合情報などありませんか?
情報がないとバージョンアップもできないので。
正直その情報量ではなんともいえないな。
どんなデータを読み込んでいるかも分からんので、推測になるがまずは改行コードでも疑ってみたら?
Perl 側の改行コード判定は $/ の変数の値だ。
あとは一気に全部読み込もうとしてるがこれはメモリ使用量を食うのでお勧めはしない。
とはいえ、今回の現象とは関係ないだろうが。
あとはいまどきのコードとしてはファイルハンドルの使い方がうまくないな。
ファイルハンドルはグローバルスコープをもつので重複があると厄介
eval { open( my $fh, $filename ) ) or die "Can't open file!: $filename, $!"; while ( my $line = <$fh> ){ # ほにゃらら。 } close($fh) or die "Can't close file!: $filename, $!"; } if ( $@ ) { # $@ 変数にエラーメッセージが格納される。 # エラー処理 }
バイナリファイルなら、もう一手間要るけど。
正直その情報量ではなんともいえないな。
どんなデータを読み込んでいるかも分からんので、推測になるがまずは改行コードでも疑ってみたら?
Perl 側の改行コード判定は $/ の変数の値だ。
あとは一気に全部読み込もうとしてるがこれはメモリ使用量を食うのでお勧めはしない。
とはいえ、今回の現象とは関係ないだろうが。
あとはいまどきのコードとしてはファイルハンドルの使い方がうまくないな。
ファイルハンドルはグローバルスコープをもつので重複があると厄介
eval { open( my $fh, $filename ) ) or die "Can't open file!: $filename, $!"; while ( my $line = <$fh> ){ # ほにゃらら。 } close($fh) or die "Can't close file!: $filename, $!"; } if ( $@ ) { # $@ 変数にエラーメッセージが格納される。 # エラー処理 }
バイナリファイルなら、もう一手間要るけど。
教えていただいた$/で$/="\n";と読み込む前に強制的に書き換えると現象が出なくなりました。
中に何が入っていたのかわかりませんが、何かのプログラムで書き換えられていたようです。
ただ読み込む前に全て代入しないと無理ですよね。
他の人の作ったプログラムも大量に載っているので…。
ただ読み込む前に全て代入しないと無理ですよね。
他の人の作ったプログラムも大量に載っているので…。
そりゃあつらいな。
知ってのとおり、mod_perl は永続化する。
グローバル変数なんでいじった日には逆に他のプログラムのほうで逆のエラーが出る羽目になる。
場当たり的だが回避策としては、このぐらいか。
my @array = split "\n", <FH>;
use strict; use warnings; local $/ = "\n";
local 構文はレキシカルスコープだから他のプログラムに影響を与えることは無いはず。
もうちょっときれいな解決策もありそうだけどなー。
教えていただいた$/で$/="\n";と読み込む前に強制的に書き換えると現象が出なくなりました。
中に何が入っていたのかわかりませんが、何かのプログラムで書き換えられていたようです。
ただ読み込む前に全て代入しないと無理ですよね。
他の人の作ったプログラムも大量に載っているので…。