goto in CORE :: GLOBAL :: exit-レーキはどこですか?

FastCGIで実行したいCGIがあります。

htmlテンプレートを処理し、ブラウザにエラー(ダイ)を表示し、あらゆる種類のリダイレクトを行い、ファイルを提供するなどのフレームワークを使用します。 -すべてがいつも通りです。 このフレームワークは、応答を形成してSTDOUTに出力した後、 exit()を実行します。これは一般的にはオリジナルではありません。

このexit()は、 eval() 、または複数のネストされたeval-sの内部で呼び出すことができます。たとえば、計算の深さのどこかで、CGIがユーザーにリダイレクトを与えることを決定します。 同時に、フレームワークの関数を呼び出し、 print "Location: ..."を出力してexit()ます。

ただし、FastCGIのexit()できません。

したがって、この出口をインターセプトし、 die() (たとえばmod_perl 行うように)またはgotoます。 die()の問題は、 exit()eval()内で呼び出され、 eval()を呼び出した後、ユーザーがdie()再度呼び出して上記の未知のエラーを渡さないことです(ただし、このCGIボックスでevalが行われるたびにこの動作を保証します)私はできません-むしろ、これが通常起こらないことを保証できます)、 exit()は単に最も近いeval()からの出口につながりますが、リダイレクトを引き起こしたCGIshopは明らかにカウントしませんでした!

CGI擬似コード


sub that_cgi_script {
...
eval { do_something() };
...
}
sub do_something {
# 1) may return if everything ok
# 2) may die on error, but such error non-important to
# calling code in above case and will be catched by
# eval and ignored
# 3) may redirect: print Location header and call exit()
}

ダイを介したオプション出口


my $FCGI_EXIT = "FCGI NORMAL EXIT\n";
BEGIN { *CORE::GLOBAL::exit = sub { die $FCGI_EXIT }; }
while (CGI::Fast->new()) {
eval { that_cgi_script(); };
die $@ if $@ && $@ ne $FCGI_EXIT;
$CGI::Fast::Ext_Request->Finish();
}

gotoによるバリアント出口


BEGIN { *CORE::GLOBAL::exit = sub { goto EXIT }; }
while (CGI::Fast->new()) {
eval { that_cgi_script(); };
die $@ if $@;
EXIT:
$CGI::Fast::Ext_Request->Finish();
}

perldoc -f gotoの説明


サブルーチンや「foreach」ループなど、初期化を必要とする構造体には使用できません。 また、最適化された構造に移動したり、「ソート」に指定されたブロックやサブルーチンから抜け出すために使用することもできません。

それでは、熊手はどこにありますか?


この状況に適用できるgotoの唯一の問題は、 sort内でexit()呼び出すsortです。 :)このCGIではそのようなことが許可されていないと心から信じています。 アーメン

CORE::GLOBAL::exit gotoを使用する場合、他にレーキになり得るものは何ですか? 私が心配しているのは、mod_perl gotoは使用しないことですが、 die()よりも効率的なソリューションのようです。

Source: https://habr.com/ru/post/J13681/


All Articles