エラーメッセージは「何が、なぜ、どこで、いつ」を書く
サブルーチンを使用する側にたって、メッセージを書くこと。そっけないメッセージはダメ。問題の全容、その理由、発生した場所、呼び出し元での失敗したソース行を示すこと。
エラーメッセージの分かり易い解説をドキュメントに書く
コードから生成される可能性のある例外、警告をドキュメントにすることが大事。perldiagの標準マニュアルは平易な文章でエラー内容を記述してあり、お手本になる。例外オブジェクトを使用する
perl5.005以降では、ブレスされた参照(オブジェクト)をdieまたはcroakに渡せるようになった。オブジェクトを例外として使用する利点は2つある。
1つ目は、例外オブジェクトを型で検出できること。例外クラスのcaught()メソッドを使用する。
#get_number()内で以下のような記述があるとする
#X::TooBigという例外クラスをcroakに直接わたす。
#croak(X::TooBig->new( {value=>$num, range=>[0, $MAX_ALLOWED_VALUE]} ) )
#if $num > $MAX_ALLOWED_VALUE;
my $value = eval { get_number() };
if ($EVAL_ERROR) { #例外を補足。例外には例外オブジェクトが入っているかもしれない。
if ( X::TooBig->caught() ) {#例外オブジェクトがX::TooBigクラスに属している
my @range = $EVAL_ERROR->get_range();
$value = $range[-1];
}
elsif( X::TooSmall->caught() ) {#例外オブジェクトがX::TooSmallクラスに属している
$value = $EVAL_ERROR->get_value();
}
}
else {
croak( $EVAL_ERROR);
}
#例外オブジェクト内のcaughtメソッドを抜粋
sub caught {
my ($this_class) = @_;
use Scalar::Util qw( blessed );
return if !blessed $EVAL_ERROR; #EVAL_ERRORはオブジェクトでないならfalseをリターン
return $EVAL_ERROR->isa($this_class); #$EVAL_ERRORがオブジェクトで、かつ、このクラスに属しているなら真
}
二つ目のメリットは、複雑なデータ構造を例外オブジェクトに詰め込んで例外ハンドラに渡せること。
例外ハンドルには、実際のハンドルが含まれているため、再試行できる可能性がある。
croak( X::EOF->new({ handle => $fh }) )
if $fh->eof();
0 件のコメント:
コメントを投稿