人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

Perlの質問です。CGIで呼ばれるプログラムでファイルの読み込みが失敗し困っています。
具体的には読み込み自体は成功するのですが、以下のような一般的(と思うんですが)複数行あるはずのデータが一行になって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は問題があるプログラムではつけいるしエラー、警告は出ていません。
ただしつけてないプログラムが同じサーバに同居しています。
たぶんメモリ関係だと思うのですが。

なにか関連するモジュールでの不具合情報などありませんか?
情報がないとバージョンアップもできないので。

●質問者: komamix
●カテゴリ:コンピュータ ウェブ制作
✍キーワード:2.0 Apache CGI Es mod_perl
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● b-wind
●90ポイント ベストアンサー

正直その情報量ではなんともいえないな。

どんなデータを読み込んでいるかも分からんので、推測になるがまずは改行コードでも疑ってみたら?

Perl 側の改行コード判定は $/ の変数の値だ。

perlvar - 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";と読み込む前に強制的に書き換えると現象が出なくなりました。

中に何が入っていたのかわかりませんが、何かのプログラムで書き換えられていたようです。

ただ読み込む前に全て代入しないと無理ですよね。

他の人の作ったプログラムも大量に載っているので…。


2 ● b-wind
●10ポイント

ただ読み込む前に全て代入しないと無理ですよね。

他の人の作ったプログラムも大量に載っているので…。

そりゃあつらいな。

知ってのとおり、mod_perl は永続化する。

グローバル変数なんでいじった日には逆に他のプログラムのほうで逆のエラーが出る羽目になる。


場当たり的だが回避策としては、このぐらいか。

my @array = split "\n", <FH>;
use strict;
use warnings;

local $/ = "\n";

local 構文はレキシカルスコープだから他のプログラムに影響を与えることは無いはず。

もうちょっときれいな解決策もありそうだけどなー。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ