#navi_header|Perl| エラーメッセージを表示させるのに一番よく見かけるのが "warn" と "die" である。 それに追随して、PerlのCoreModule((少なくもPerl5.8系列ではCoreModule))の '' Carp '' もよく使われているようである。 このモジュールは、簡潔にまとめると、「よりユーザー・開発者に分かりやすいエラーメッセージを提供する」ためのものである。サブルーチンの呼び出し履歴(バックスタックトレース)を付けてくれる、などである。 - perldoc : http://perldoc.perl.org/Carp.html - perldoc(ja) : http://perldoc.jp/docs/perl/5.8.0/Carp.pod * (carp, croak) と (cluck, confess) の違い 今回示すような簡単なコードピースでは違いは表面化しないのかも知れない。実際、carp(or croak)も、cluck(or confess)も、全く同じ結果になってしまった。厳密には、上記perldocで記述されているが以下のような違いがあるらしい。 - cluck(warn相当), confess(die相当) : コールスタック内の全ての呼び出しに関する要約がついてくる。 - carp(warn相当), croak(die相当) : より短いメッセージを出力する。(モジュールが呼び出された位置からエラーをリポートすることが可能?) ・・・よく分からないので、将来のリベンジとして残しておく。 * 4つの意味の違い 正直なところ、英辞郎などを引いてみても、細かいニュアンスの差になってしまい区別が付かなかった・・・。 - carp : 難癖をつける、あら探しをする? - croak : 蛙がゲコゲコなく、ブツブツ不平をこぼす? - cluck : めんどりが鳴く、舌打ちをして不平を言う? - confess : 間違い・罪を認める、白状する? * コードピースと出力($SIG{__WARN__}, $SIG{__DIE__}) - コードピース : carp01.pl (carp, croakの実験) #!/usr/bin/perl use strict; use warnings; use Carp; # "warn"発生時のシグナルハンドラ sub w01 { print "======= WARN SIGNAL HANDLER\n"; my ($msg) = @_; print $msg, "\n"; } $SIG{__WARN__} = \&w01; # "die"発生時のシグナルハンドラ sub d01 { print "======= DIE SIGNAL HANDLER\n"; my ($msg) = @_; print $msg, "\n"; } $SIG{__DIE__} = \&d01; sub f01 { &f02(); } sub f02 { &f03(); } sub f03 { carp("OOPS!!"); #croak("OOPS!!"); }; eval { &f01(); }; if ($@) { print '------- $@ is caught', "\n"; warn $@; } - 出力1 : warn相当の"carp"時 $ ./carp01.pl ======= WARN SIGNAL HANDLER OOPS!! at ./carp01.pl line 32 main::f03() called at ./carp01.pl line 28 main::f02() called at ./carp01.pl line 24 main::f01() called at ./carp01.pl line 37 eval {...} called at ./carp01.pl line 36 - 出力2 : die相当の"croak"時 $ ./carp01.pl ======= DIE SIGNAL HANDLER OOPS!! at ./carp01.pl line 33 main::f03() called at ./carp01.pl line 28 main::f02() called at ./carp01.pl line 24 main::f01() called at ./carp01.pl line 37 eval {...} called at ./carp01.pl line 36 ------- $@ is caught ======= WARN SIGNAL HANDLER OOPS!! at ./carp01.pl line 33 main::f03() called at ./carp01.pl line 28 main::f02() called at ./carp01.pl line 24 main::f01() called at ./carp01.pl line 37 eval {...} called at ./carp01.pl line 36 warnとdieを処理する、特別なシグナル処理、 '' $SIG{__WARN__}, $SIG{__DIE__} '' を使用し、本当にdie相当/warn相当が処理されているのかを確認してみる。その結果 carp を用いると、確かにwarn用のシグナルハンドラが走っていることがわかる。また、croakの場合、一度die用のシグナルハンドラが走ってから(これ自体はdie相当ということで問題ない)、 '' $@がセットされる '' ため、下のwarn処理に走り、それにより今度はwarn用のシグナルハンドラが走っている。 続いて carp, croak を cluck, confessに変えてみる。コードピースは省略する。 - 出力1 : warn相当の"cluck"時 $ ./carp01.pl ======= WARN SIGNAL HANDLER OOPS!! at ./carp02.pl line 32 main::f03() called at ./carp02.pl line 28 main::f02() called at ./carp02.pl line 24 main::f01() called at ./carp02.pl line 37 eval {...} called at ./carp02.pl line 36 - 出力2 : die相当の"confess"時 $ ./carp01.pl ======= DIE SIGNAL HANDLER OOPS!! at ./carp02.pl line 33 main::f03() called at ./carp02.pl line 28 main::f02() called at ./carp02.pl line 24 main::f01() called at ./carp02.pl line 37 eval {...} called at ./carp02.pl line 36 ------- $@ is caught ======= WARN SIGNAL HANDLER OOPS!! at ./carp02.pl line 33 main::f03() called at ./carp02.pl line 28 main::f02() called at ./carp02.pl line 24 main::f01() called at ./carp02.pl line 37 eval {...} called at ./carp02.pl line 36 '' このように、carp/croakと出力に差異は見られなかった。 '' 恐らく簡単なコードピースではこの差異は表に出てこないと思われる。 とはいえ、cluck/confessでも、warn相当/die相当でシグナルハンドラが処理されていることを確認できた。 #navi_footer|Perl|