D 2.0
About Japanese Translation

Last update Sun Dec 19 23:27:25 2010

std.exception

このモジュールは例外や、 一般のエラー処理のためのツールを定義しています。

Synopsis:
 string synopsis()
 {
     FILE* f = enforce(fopen("some/file"));
     // ここから先は f は必ず null でない
     FILE* g = enforceEx!(WriteException)(fopen("some/other/file", "w"));
     // ここから先は g は必ず null でない
     Exception e = collectException(write(g, readln(f)));
     if (e)
     {
         ... 例外が発生した場合 ...
     }
     char[] line;
     enforce(readln(f, line));
     return assumeUnique(line);
 }

Source:
std/exception.d

License:
Boost License 1.0

Authors:
Andrei Alexandrescu
T enforce(T, string file = __FILE__, int line = __LINE__)(T value, lazy const(char)[] msg = null);
If value が非ゼロならそのまま返し、そうでなければ new Exception(msg) 例外を投げます

Example:
 auto f = enforce(fopen("data.txt"));
 auto line = readln(f);
 enforce(line.length); // 空行を期待

T enforce(T)(T value, lazy Exception ex);
value が非ゼロなら、その値を返します。 そうでなければ、例外 ex を投げます。

Example:
 auto f = enforce(fopen("data.txt"));
 auto line = readln(f);
 enforce(line.length, new IOException); // 空行を期待

T errnoEnforce(T, string file = __FILE__, int line = __LINE__)(T value, lazy string msg = null);
value が非ゼロなら、その値を返します。それ以外の場合、new ErrnoException(msg) を投げます。ErrnoException クラスは、 最後の動作が errno にエラーコードを設定したことを仮定しています。

Example:
 auto f = errnoEnforce(fopen("data.txt"));
 auto line = readln(f);
 enforce(line.length); // 空でない行を期待

template enforceEx(E)
value が非ゼロならそのまま返し、そうでなければ new E(msg) を投げます

Example:
 auto f = enforceEx!(FileMissingException)(fopen("data.txt"));
 auto line = readln(f);
 enforceEx!(DataCorruptionException)(line.length);

Exception collectException(T)(lazy T expression, ref T target);
expression を評価して、その結果例外が発生したらその例外を返します。 それ以外では、式の評価結果を target に格納し、null を返します。

Example:
 int[] a = new int[3];
 int b;
 assert(collectException(a[4], b));

Exception collectException(T)(lazy T expression);
expression を評価して、その結果例外が発生したらその例外を返します。 それ以外の場合は null を返します。Tvoid でも構いません。
immutable(T)[] assumeUnique(T)(ref T[] array);
書き換え可能な配列をimmutable配列に書き換えるイディオムです。 実装としては、assumeUnique は単純にキャストを行うだけです。 しかし、この名前を使うことで、arrayへの参照が他に残っていないという仮定をしていることが ソースから読み取れるようになります。 assumeUnique(arr) は、他に arr の要素を指すmutable参照が決して残っていない時にのみ呼び出されるべきです。この仮定を強固にするために、 assumeUnique(arr) はreturnする前に引数 arrnullクリアします。本質的には、assumeUnique(arr) は呼び出し側の 「もう arr の(推移的)要素を書き換える参照は他にない」 「この先の操作は全て assumeUnique の返すimmutable配列に対して行う」という決意表明と言えます。

良くある例としては、assumeUnique は関数内でメモリを割り当て中身を構築した配列を返すときに使われます。

Example:
 string letters()
 {
   char[] result = new char['z' - 'a' + 1];
   foreach (i, ref e; result)
   {
     e = 'a' + i;
   }
   return assumeUnique(result);
 }
resultletters 関数内のローカル変数で、関数が return した後に書き換わることがないので、 上の例は正しい使い方です。これに対して次の例は、 assumeUnique の間違った使い方です。

Bad:
 private char[] buffer;
 string letters(char first, char last)
 {
   if (first >= last) return null; // fine
   auto sneaky = buffer;
   sneaky.length = last - first + 1;
   foreach (i, ref e; sneaky)
   {
     e = 'a' + i;
   }
   return assumeUnique(sneaky); // BAD
 }
この例はクライアント側のコードを破滅させてしまいます。 呼び出し側に対しては変更されないと宣言されている配列を書き換えているからです。 書き込み可能な配列 buffer から正しく immutable な配列を得るには、 最後の行をこうします:
 return to!(string)(sneaky); // 大丈夫
このコードは適切に配列のコピーを作成します。

参照が一つしかないことをコンパイル時に保証するのは、特定の場合では可能です (ArchJava 言語の uniquelent キーワード)が、 言語がかなり複雑になります。 assumeUnique のような慣習に基づいた方法の欠点は、 現時点では仮定の正しさをフォーマルに検証する術がなにもないことです。一方で利点は、 一方で利点は、このような assumeUnique の使い方はシンプルで、まあまあ使う気になれるところです。
bool pointsTo(S, T)(ref const S source, ref const T target);
source の表現が target の表現もしくはその内部を指すポインタを含んでいる場合、 true を返します。pointsTo(x, x) とすると、x が自分自身を指すポインタを含んでいるかどうかのチェックとなります。

class ErrnoException: object.Exception;
errno を設定するエラーが発生したときに投げられる例外