Go to the first, previous, next, last section, table of contents.

エラー(制御構造)

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


Go to the first, previous, next, last section, table of contents.