Lisp が(ある)フォームの評価を行なおうとし、何らかの理由でそれが評価できなかっ た場合、エラーが生じます。エラーはイベント(訳注:event)であり、このイベントを 名付ける(対応した) エラーシンボルやエラー名を持っています。エラーが生じた場 合、(Emacs は)通常の評価シーケンスをサスペンドし、そのエラーに対するハンドラを 探します。エラーは、(特別な)エラーハンドラで扱われるか、 (扱われない場合)全て の計算をアボートし(Emacs を) コマンドループに戻します。エラーに対するエラーハ
ンドラが見つかった場合、それに制御を渡し、エラーイベントは終ったものとします。
エラーのハンドリングやトラッピングは、タグをキャッチすることとは区別して考えな くてはいけません。エラーを throw したり catch することはできません。タグを signal したり handle することはできません。セクション 12.6 [throw]、ページ 104 参照。
Lisp 関数(と primitive 関数)の中では、signal を呼ぶことでエラーが出されます。 ハンドラは、Lisp のコードで condition-case を呼ぶことで確立されます。 condition-case エラーハンドラにおいて、各エラーシンボルは、 (どのエラーを扱う かを示す) 1つもしくはそれ以上のエラーコンディションを(それぞれ)持ちます。
(ある)エラーハンドラがどのように処理を行なうかは、 (そのエラーハンドラに)まか されています。全く異なるフォームを実行し、その結果を返しても、別のエラーを出し てもかまいません。できないことは、アボートした計算を "再開 (訳注:resume)" す ることです。スタックはエラーハンドラの部分までポップされているため、その下の部 分は(全て)失われています。 signal は(それが再び呼ばれない限り)再び制御を得るこ とはありません(訳注:??)。
ハンドラは、エラーになった式がやろうとしたことを行なおうとするかもしれません が、これは (デバッガで)計算を "直す" ことや、エラーが出された場所から再開する こととは違います。
----------------
CN: 関数 signal はエラーを出すことのできる唯一の関数 (エラーがコールする関数) です。これは、GNU Emacs Lisp が Common Lisp における continuable errors の概念 のようなものを(何も) 持たないことを意味します。
----------------
Function: signal symbol data
この関数は、 symbol で名付けられたエラーを出し(訳注:signal)ます。呼ばれた 場合、signal はスタックをサーチし(symbol が対応付けられている)エラーコン ディションを指定するハンドラを求めます。それが(1つ)見つかると、制御をそこ から再開(訳注:resume) します。見つからない場合、Emacs は data から作られ るエラーメッセージを表示し、カレントの recursive-edit レベル(必ずしもトッ プレベルではありません)のコマンドループに戻ります。
debug-on-error が non-nil の場合、コマンドループにアボートするかわりに、デ バッガを起動します。
symbol は、そのプロパティーリスト中に、コンディション名(セクション 12.7.1 [エラーコンディション]、ページ 110 参照)のリストを値として持つ error- conditions プロパティーを持たなくてはいけません。それを持たない場合、ト ラップ不可能な `peculiar error' が出されます。
data はリストでなくてはいけません。 condition-case ハンドラが存在しなかっ た場合、 data の要素をエラーメッセージの部分として print します。 condition-case ハンドラが存在した場合、 data と symbol をコンスし、それを condition-case の変数にバインドします。
(signal 'wrong-number-of-arguments (list "Oh, Rats!" (1+ 1) "many arguments again."))
---------- Echo Area ---------- Wrong-number-of-arguments: "Oh, Rats!", 2, "many arguments again." -------------------------------
(signal 'no-such-error '("My unknown error condition."))
---------- Echo Area ---------- peculiar error: "My unknown error condition." -------------------------------
Special Form: condition-case var form handlers*
この特殊フォームは、エラーが出さ(訳注:signal)れた場合、 (処理の全体をア ボートするのではなく) Lisp プログラムが、そのエラーを扱うことができるよう にします。 condition-case フォームは評価されると、まず (signal が探す)特殊 なマーカーをスタック上に置きます。次に、 form を評価します。 form がエラー を生ずることなく評価された場合、その結果を condition-case の値とします。
form の評価中にエラーが出さ(訳注:signal)れた場合、 signal は condition- case マークを見つけるまでスタックをサーチし、 (現われた順に) そ handlers を見ていきます。各ハンドラは、(condition-name body*) といった形をしていま す。
あるハンドラ中の condition-name が、そのエラーシンボルに対応付けられたコン ディションの 1つである場合、そのハンドラを用います。 (最初に)変数 var に、 (それを持って signal が呼ばれた)リスト data と (condition-name ではなく)エ ラーシンボルとをコンスしたリストをバインドします。 (次に) body フォームを 評価し、その最後の値を結果とします。
condition-case が、(その)どのコンディションに対するハンドラも持たない場 合、signal はそのエラーを扱う(別の) condition-case がスタック上に存在しな いか調べ(続け)ます。見つからなかった場合、処理(訳注:computation)をアボー トします。
以下に示した例の最初の例において、 0 で割ると arith-error が出さ(訳注: signal)れ、それは (対応する)コンディションを 2つ (arith-error と error) 持っています。このエラーはワーニングメッセージを print out することと、非 常に大きな数を返すことで扱われます。
2 番目の例において、(対応するコンディションとして quit のみを持つ) エラー quit は、condition-case の外で扱われます。これは、condition-case の内部で 扱えるのは error という名前のコンディションに対応するエラーのみであるため です。
(condition-case ERR (/ 3 0)
(error (princ (format "\nThe error was: %s" ERR)) 1000000)) -> The error was: (arith-error) => 1000000 (condition-case ERR0 (condition-case ERR1 (signal 'quit "No go") (error (print (format "\This was caught by CC1: %s" ERR1)) 'VALUE1)) (quit (print (format "\This was caught by CC0: %s" ERR0)) 'VALUE0)) -> This was caught by CC0: (quit . "No go") => VALUE0
condition-case は、クリーンアップやリカバリーを試みることができるよう、予 想しない(訳注:unexpected)エラーのトラップ用に用いることができます。また、 予期されたエラーをトラップし、 (標準的な) Emacs 関数の使用に対し機能追加を 行なうことができます。以下に示した例において、 down-list 関数は括弧を 1レ ベル下げることができるか否かを調べるのに用いられます。 quit はカレントの処 理のアボートを意図したものであるため、通常はトラップすべきではありません。
(condition-case err (down-list 1) (error (message "Hit bottom")) ) => "Hit bottom"
Function: error format-string &rest args
このフォームは、 error という名前のエラーと、 format (セクション 5.3 [format]、ページ 45 参照) をアーギュメントに適用することで作られるストリン グとを持って signal を呼んで、エラーを出します。
(setq BAZ 34) => 34 (if (eq BAZ 35) t (error "Rats! The variable %s was %s, not 35." 'BAZ BAZ))
---------- Echo Area ---------- Rats! The vaiable BAZ was 34, not 35 -------------------------------
(condition-case ERR (if (eq BAZ 35) t (error "Rats! The variable %s was %s, not 35." 'BAZ BAZ)) (error (princ (format "\nThe error was: %s" ERR)) 2)) -> The error was: (error "Rats! The variable %s was %s, not 35.") => 2