名前¶
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 <[email protected]>
The code that inspired me to write this was originally written by Peter Seibel <[email protected]> and adapted by Jesse Glick <[email protected]>.
このコードはもともとPeter Seibel <[email protected]>が書き、その後 Jesse Glick <[email protected]>により引き継がれたコードによってインスパイア されました。
メンテナ¶
Arun Kumar U <[email protected]>
翻訳者¶
萩原佳明 ([email protected])