エラーメッセージを表示させるのに一番よく見かけるのが "warn" と "die" である。
それに追随して、PerlのCoreModule(*1)の Carp もよく使われているようである。
このモジュールは、簡潔にまとめると、「よりユーザー・開発者に分かりやすいエラーメッセージを提供する」ためのものである。サブルーチンの呼び出し履歴(バックスタックトレース)を付けてくれる、などである。
今回示すような簡単なコードピースでは違いは表面化しないのかも知れない。実際、carp(or croak)も、cluck(or confess)も、全く同じ結果になってしまった。厳密には、上記perldocで記述されているが以下のような違いがあるらしい。
・・・よく分からないので、将来のリベンジとして残しておく。
正直なところ、英辞郎などを引いてみても、細かいニュアンスの差になってしまい区別が付かなかった・・・。
#!/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 $@; }
$ ./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
$ ./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に変えてみる。コードピースは省略する。
$ ./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
$ ./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相当でシグナルハンドラが処理されていることを確認できた。
コメント