名前¶
Error - エラーや例外をオブジェクト指向的に扱う
概要¶
use Error qw(:try);
throw Error::Simple( "A simple error");
sub xyz {
...
record Error::Simple("A simple error")
and return;
}
unlink($file) or throw Error::Simple("$file: $!",$!);
try {
do_some_stuff();
die "error!" if $condition;
throw Error::Simple -text => "Oops!" if $other_condition;
}
catch Error::IO with {
my $E = shift;
print STDERR "File ", $E->{'-file'}, " had a problem\n";
}
except {
my $E = shift;
my $general_handler=sub {send_message $E->{-description}};
return {
UserException1 => $general_handler,
UserException2 => $general_handler
};
}
otherwise {
print STDERR "Well I don't know what to say\n";
}
finally {
close_the_garage_door_already(); # ここには信頼できるものを
}; # 最後の ; を忘れないように。びっくりしてしまうと思うので
説明¶
Errorパッケージはふたつのインターフェースを提供します。まず、Errorは 例外を扱うための手続き型インターフェースを提供します。またErrorは、throw したり、あとでcatchしたり、もしくは単にrecordしたりするための、エラーや例外の ベースクラスとなることができます。
Errorクラスのエラーを直接throwするべきではありません。Errorのサブクラス を使ってエラーを投げるようにしてください。
手続き型インターフェース¶
Errorは例外を扱うためのサブルーチンをエクスポートします。これらの サブルーチンをエクスポートするには、useでの宣言時に:tryタグを 指定してください。
- try BLOCK CLAUSES
-
tryはユーザーから呼ばれるメインのサブルーチンです。エクスポートされた 他のすべてのサブルーチンは、tryサブルーチンの節になります。tryはBLOCKを評価し、その結果エラーが投げられることがなければ、そのブロック の実行結果を返します。
CLAUSESは後に続くサブルーチンで、BLOCK内でエラーが投げられた場合何を行うのか について記述してあります。 - catch CLASS with BLOCK
-
BLOCKを評価しているときにcatchされたエラーが$err->isa(CLASS)を満たす 場合、この節が呼び出されます。BLOCKにはふたつの引数が渡されます。ひとつ目はthrowされたエラーです。 ふたつ目はスカラー変数へのリファレンスです。もしこの変数がcatchブロックで セットされると、catchブロックから返るときに、tryはあたかもcatchブロックが 見つからなかったかのように処理を継続します。再度エラーを投げるにはcatchブロック内で
$err->throwを呼び出します。第2引数のスカラーリファレンスがセットされていない場合、エラーが投げられません。 そして現在実行中のtryブロックは、catchブロックの結果をそのまま返します。
- except BLOCK
-
tryがハンドラを見つけられなかった場合、except節が見つかるとBLOCKが 評価されます。このブロックからの戻り値は、キーがクラス名で、値がそのタイプの エラーをハンドルするCODEリファレンスであるHASHREFか、同様のキーと値のペアの リストである必要があります。 - otherwise BLOCK
-
どんなエラーであろうと補足し
BLOCK中のコードを実行します。BLOCKが評価される際に引数がひとつ渡されますが、これは現在処理されている エラーです。otherwiseブロックはtryブロックひとつにつきひとつしか指定できません。
- finally BLOCK
-
tryブロック中のコードの実行が成功した場合、
BLOCKにあるコードが実行されます。 tryブロックがエラーを投げた場合は、エラーハンドラが終了したあとでBLOCK中の コードが実行されます。エラーハンドラがエラーを投げた場合そのエラーは補足され、finallyブロックが実行 されたあと再度そのエラーが投げられます。
finallyブロックはtryブロックひとつにつきひとつしか指定できません。
クラスインターフェース¶
コンストラクタ¶
Errorオブジェクトはハッシュとして実装されています。このハッシュは コンストラクタに渡される引数で初期化されます。使用できる引数、つまり Errorクラスから利用できる要素は以下の通りです。ただし、他のクラスが 他の要素を追加しても構いません。
-file
-line
-text
-value
-object
-fileや-lineがコンストラクタの引数に指定されていなかった場合、これらは コンストラクタの呼び出し元のファイル名や行番号で初期化されます。
エラーが特定のオブジェクトと関連を持っているようなら、そのオブジェクトを -object引数で渡してください。こうするとErrorパッケージはそのオブジェクト と関連を持つことができます。
Errorパッケージは、最後に生成されたエラーを覚えているだけではなく、 あるパッケージに関連した最後のエラーについても覚えています。このエラーは、 そのパッケージ中のサブルーチンで作られた最後のエラーである場合もあれば、 blessされたオブジェクトを-object引数でそのパッケージに渡した最後のエラー である場合もあります。
- throw ( [ ARGS ] )
-
新しい
Errorオブジェクトを生成し、エラーを投げます。このエラーは、外側にtryブロックがあればcatchされ、なければプログラムを終了させます。throwは既存のエラーを再度投げるときにも呼び出されます。 - with ( [ ARGS ] )
-
新しい
Errorオブジェクトを生成して返します。これは以下のような場合の シンタックスシュガーのため定義されています。die with Some::Error ( ... ); - record ( [ ARGS ] )
-
新しい
Errorオブジェクトを生成して返します。これは以下のような場合の シンタックスシュガーのため定義されています。record Some::Error ( ... ) and return;
スタティックメソッド¶
- prior ( [ PACKAGE ] )
-
最後に生成されたエラー、もしくは
PACKAGEに関連する最後のエラーを返します。
オブジェクトメソッド¶
- stacktrace
-
エラーが生成された際に
$Error::Debug変数が0でない場合、stacktraceはCarp::longmessを呼び出した結果の文字列を返します。もし変数が0なら、stacktraceはエラーの文字列に、そのエラーが生成されたファイルのファイル名と 行番号を追加した文字列(最後に改行は付かない)を返します。 - object
-
このエラーと関連付けられているオブジェクト。
- file
-
このエラーのコンストラクタが呼び出されたファイル。
- line
-
このエラーのコンストラクタが呼び出された行番号。
- text
-
エラーのテキスト。
オーバーロードされたメソッド¶
- stringify
-
オブジェクトを文字列に変換するメソッド。このメソッドは、単純に
textメソッド と同じものを返すか、たとえばファイル名や行番号など、もう少し情報が付加された ものを返します。デフォルトでは、このメソッドはコンストラクタに渡された
-text引数を返します。 何も渡されなかった場合は"Died"を返します。 - value
-
エラーと関連する値を返すメソッド。たとえばシステムコールのせいでエラーが 生成された場合は、そのときの
$!の数値を返すことでしょう。デフォルトでは、このメソッドはコンストラクタに渡された
-value引数の値を 返します。
定義済みのエラークラス¶
- Error::Simple
-
このクラスは単純なエラー文字列や値を保持したいときに使われます。 コンストラクタはふたつの引数を取ります。最初の引数はテキストの値で、 次の引数は数字の値です。これらの値はオーバーロードされたメソッドによって 返されます。
もしテキストの値が$@の文字列のように
at file line 1という風に終わるなら、 この情報はエラーオブジェクトの-file引数と-line引数をセットするのに 使われるでしょう。このクラスはevalされたブロックが単純な文字列のエラーでdieしたときに、内部的に 使われます。
既知のバグ¶
いまのところはありません。が、本当にバグ無いという意味ではありません。
作者(=AUTHORS)¶
Graham Barr <gbarr@pobox.com>
The code that inspired me to write this was originally written by Peter Seibel <peter@weblogic.com> and adapted by Jesse Glick <jglick@sig.bsh.com>.
このコードはもともとPeter Seibel <peter@weblogic.com>が書き、その後 Jesse Glick <jglick@sig.bsh.com>により引き継がれたコードによってインスパイア されました。
メンテナ¶
Arun Kumar U <u_arunkumar@yahoo.com>
翻訳者¶
萩原佳明 (hagi@p1d.com)