私はperlファイルbuild_ios.pl
を10-20の方法で使用しています。Perlスクリプトが 'サブルーチンの深い再帰'に固執しました
私は私のビルドマシン/usr/bin/perl /Users/snaggs/scripts/build_ios.pl
上で実行すると、私はエラーを取得する:このエラーの
sub writeLogAndPrint
{
my $command = shift || "";
open(my $fh, '>>', $VERBOSE_LOG_FILE_ABS) or # line 167
af_exit(%ERROR_CODE_12);
#die "Can't open the file: $!";
print $fh getTimeLoggerHelper() . ": " . $command."\n";
close $fh;
print $command . "\n";
}
sub af_exit
{
my %_error = @_;
writeLogAndPrint($_error{'id'}); # line 179
exit($_error{'id'});
}
とスクリプトstucks:ここ
Deep recursion on subroutine "main::writeLogAndPrint" at /Users/snaggs/scripts/build_ios.pl line 179.
Deep recursion on subroutine "main::af_exit" at /Users/snaggs/scripts/build_ios.pl line 167.
はにそのエラーポイント関連するメソッドです。私のビルドマシンはバージョンv5.18.2
を使用しています。
ローカル私は同じコードを実行し、すべて正常に動作しますv5.16.0
。
私のコードで何が問題なのですか?これを取り除く方法は?
[EDIT]
私はaf_exit
通話writeLogAndPrint
とwriteLogAndPrint
は、それが無限ループに
おかげで、あなたが開こうとしているあなたのwriteLogAndPrint
サブ以内
私は、かなり直接的なエラー処理を採用するために 'open'を提案します。さもなければ、 '$!'などのエラー情報が失われるかもしれません - エラーが起きた後はかなり良い_right_です。その後、次の操作で上書きまたは空白になることがあります。少なくとも、すぐにそれらを取得し、エラー処理ルーチンに渡します。 – zdim
'af_exit'の' write_AndPrint' * OR * 'called_from_writeLog'スイッチに' $ called_from_exit'スイッチを入れる必要があります。 'af_exit'を呼び出し、' writeLogAndPrint'を呼び出し、そのファイルを再度開いておかないで 'af_exit'を呼び出すことは、ファイルを開いていないことは明らかです。残念ながら、私は 'af_exit'に' $ called_from_writeLog'フラグを使用します。そうすれば、 'af_exit'でそのサブ関数を呼び出さないことを知ることができます。 – Axeman
'af_exit'を呼び出す代わりに' die'を使うべきです。メインスクリプトを 'eval BLOCK'にラップして例外を捕捉し、例外の場合は' af_exit'を呼び出します。次に、 'writeLogAndPrint($ _ error {'id'});}を' eval {writeLogAndPrint($ _ error {'id'})};に置き換えてください。 – ikegami