#navi_header|Perl| [[Perl/codepiece/try-catch-exception01]]で、基本的なエラーの捕捉方法を確認した。 ここでは、より実際のシーンを意識し、以下のシチュエーションでエラーを捕捉できるか確認する。 - require時に該当パッケージが存在しない時 - 呼ぼうとしたパッケージ関数が定義されていない時 いずれも perldiag(http://perldoc.perl.org/perldiag.html) では(F)(trappable fatal error)に分類されている。 * 未存在パッケージrequire・未定義関数呼び出し時のtry-catchエラー捕捉の確認 ディレクトリ構成: ./try05/ ./try05/try05.pl : main ./try05/Hoge/ ./try05/Hoge/Bohe.pm : empty package module - try05/try05.pl : #!/usr/bin/perl use strict; use warnings; use File::Basename; use Data::Dumper; use Error qw(:try); sub BEGIN { my (undef, $__base_dir, undef) = fileparse($0); push(@INC, $__base_dir); } # 存在しないパッケージをrequireしてみる。 try { my $pkg_name = "Hoge::Hoge"; eval("require $pkg_name;"); if ($@) { throw Error(-text => $@); } } catch Error with { my $e = shift; print Dumper($e), "\n"; }; # 存在しないパッケージ関数を呼んでみる。 try { my $pkg_name = "Hoge::Bohe"; eval("require $pkg_name;"); my $obj = $pkg_name->new(); } catch Error with { my $e = shift; print Dumper($e), "\n"; }; - try05/Hoge/Bohe.pm (空のパッケージモジュール) : package Hoge::Bohe; use strict; use warnings; 1; - 出力 $ ./try05/try05.pl $VAR1 = bless( { '-file' => 'try05/try05.pl', '-text' => 'Can\'t locate Hoge/Hoge.pm in @INC (@INC contains: ... try05/) at (eval 3) line 1. ', '-line' => 17, '-package' => 'main' }, 'Error' ); $VAR1 = bless( { '-file' => 'try05/try05.pl', '-text' => 'Can\'t locate object method "new" via package "Hoge::Bohe"', '-line' => '27', '-package' => 'Error' }, 'Error::Simple' ); '' まず、エラー捕捉の仕方が異なる点に注目する。 '' - 存在しないパッケージをロード: '' $@を手動チェックしている。 '' - 存在しない関数を呼び出し:try-catchに任せている。 最初、前者の方でもtry-catchに任せてみたが、 '' catchに捕捉されない '' 現象が発生した。試しに手動で$@チェックを入れてみたところ上手く行った。(evalの特性と関係するのかも知れない。) 逆に、後者の方で$@の手動チェックを入れても、そこは通らない。未定義関数の呼び出しの方では、即座にcatchへ入る(=dieがブロック中で発生している?)ようである。 いずれにせよ、パッケージモジュールロード時の eval("require $pkg_name") のエラーハンドリングは$@の手動チェックが欠かせないことを確認した。 #navi_footer|Perl|