WindowsのActivePerl5.6を使っています。dieやdieやPerl自体でエラーが発生したときに、通常なら標準エラーに出力して、abortされるが、標準エラーを出力する前に独自の関数を実行させて終わらせることは可能でしょうか?
例えば、以下は可能でしょうか?
sub myerror{
print "フック?\n";
goto MyJump;
}
print "TEST1\n";
die "これを表示させずに、別の処理(フックする方法)" ; # 標準エラーが出力されて終わる。
MyJump:
print "TEST2 ここまで表示\n";
Linuxならできるのでしょうか?
No.4ベストアンサー
- 回答日時:
> やはり、Windows環境ではwhile(1){}のループをCTRL+Cで止めた場合はは補足できないのですね。
WindowsでPerlを使う機会があまりないので詳しく調べたことがなかったのですが、ちょっと試してみたところ、手元の環境では Ctrl+C は捕捉できるようです。
- Windows 98/XP
- Perl 5.8.0
# Ctrl+C 用のシグナルハンドラを定義
$SIG{INT} = sub {
print "SIG_INT\n";
$loop = 0;
};
$loop = 1;
while ($loop) {
print "*\n";
sleep 1;
}
> 良くあるPerlのDBIで返すエラーなどは補足ができるのでしょうか?
これは eval で捕捉可能です。
詳しくはこちらをご覧ください。
http://member.nifty.ne.jp/hippo2000/perltips/dbi …
http://member.nifty.ne.jp/hippo2000/perltips/dbi …
> Windows上で補足できなくて困る割り込みはソフトウェア割り込み以外のハードウェア割り込み?っていうことでしょうか?
試しに他のプロセスから SIG_TERM を送ってみたところ、捕捉されずに終了してしまいました。捕捉できるかどうかは、割り込みの発生源には関係ないようです。どちらにしても不便なことに変わりありませんが。
No.3
- 回答日時:
die を捕捉して終了処理をフックするには、$SIG{__DIE__} を利用します。
プログラムの先頭などで
$SIG{__DIE__} = \&myerror;
としておけば、die で死ぬ前に myerror が実行されます。
myerror には die のパラメータが引数として渡され、実行後は通常通り、STDERR へのメッセージ出力とともにプログラムが終了します。
また、myerror による共通の例外処理以外に、die のケースごとにカスタマイズされた例外処理を行いたい場合は、evalブロックを併用します。
例:
# 共通の例外処理
sub myerror{
print "myerror: @_";
}
$SIG{__DIE__} = \&myerror;
eval {
die "Dying message\n";
print "このprint文は実行されません。";
};
# このevalブロック専用の例外処理
if ($@) {
print "exception: $@";
exit; # exitしなければ、その後の処理を継続できます。
}
# 実行結果
myerror: Dying message
exception: Dying message
※evalブロック内で die すると、die のパラメータが $@ に設定されてブロックを抜けます。プログラムは終了されず、STDERR へのメッセージ出力もありません。
※$SIG{__DIE__} も evalブロックも、プラットフォームに依らず利用できます。
なお、No.1 で特殊サブルーチン END を使った方法が紹介されていますが、END はプログラム終了時に必ず実行されてしまうので、die に限定した処理を行うことはできません。
ありがとうございます。
やはり、Windows環境ではwhile(1){}のループをCTRL+Cで止めた場合はは補足できないのですね。
良くあるPerlのDBIで返すエラーなどは補足ができるのでしょうか?
Windows上で補足できなくて困る割り込みはソフトウェア割り込み以外のハードウェア割り込み?っていうことでしょうか?無知ですみません。
No.2
- 回答日時:
evalを使った例外処理の方法もあります。
Javaのtry/catchの様な感じです。
例)-------------------------------------------
eval {
print "TEST1\n";
die;
};
if ($@) {
# エラーが発生したときの処理
print "TEST2 ここまで表示\n";
exit();
}
----------------------------------------------
evalのブロックの中で例外が発生した場合、ブロック中のコードの実行は終了し、$@にエラーメッセージが設定されます。ただし、シグナルやパニックの様なエラーは捕捉出来ないようです。
evalの引数にはブロックと文字列が取れますが、文字列形式ではevalを実行するたびにコンパイルが行われて負荷が高くなるので、出来るだけブロック形式をとったほうが良いでしょう。
No.1
- 回答日時:
・die、例外発生等でインタプリタが終了するとき(シグナルによる終了は除く)
END { 実行させたい内容 }
・シグナルによる終了時(Unix系列のみ)
$SIG{HUP} = $SIG{INT} = $SIG{PIPE} = $SIG{QUIT} = $SIG{TERM} = \&signal_end;
sub signal_end {
実行させたい内容
}
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
CLispのloop内の挙動について
-
Perlでページランクを取得する方法
-
Perlで自分自身の関数名を知る...
-
10進数→2進数
-
シェルでawkを使い行数を取り出...
-
icmp socket error
-
Rubyのgets関数について
-
If分がelseに流れてしまう(python)
-
ハノイの塔の問題で困っており...
-
Perl 一定時間後にプログラムを...
-
Application.ScreenUpdating = ...
-
文字の横にプルダウンを表示さ...
-
JSONで文字列が長い時
-
formで特定のinputを送信しない...
-
「*:*」って何を意味するのでし...
-
UWSC:ポップアップウインドウ...
-
同パッケージ内の関数を呼び出...
-
ACCESS テキストボックスを隙...
-
構造体の各データの表示につい...
-
セレクトボックスの内容を中央寄せ
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
CLispのloop内の挙動について
-
Perlで複数の値を返す良い方法...
-
プロトタイプ宣言のワーニング...
-
dieやPerl自体でエラーが発生し...
-
ハノイの塔の問題で困っており...
-
Net::Telnetでタイムアウト時間...
-
print <<"_HTML_"の中でサブル...
-
Net::SSH::Perlについて
-
Win98+PWS4.0でPERLが動作しま...
-
icmp socket error
-
Pythonのプログラミングの質問...
-
[perl] next と return 同じ意...
-
Perlで自分自身の関数名を知る...
-
threads を使ったマルチスレッ...
-
Rubyのgets関数について
-
Perlで use strict して our変数
-
10進数→2進数
-
変数に値を代入するのに、まずu...
-
これは動いてくれますか??
-
HASH(0xほげほげ)
おすすめ情報