@c -*-texinfo-*-
@c This is part of the GNU Emacs Lisp Reference Manual.
@c Copyright (C) 1990, 1991, 1992, 1993, 1994 Free Software Foundation, Inc. 
@c See the file elisp-jp.texi for copying conditions.
@c 複製の条件は elisp-jp.texi に書いてあります。
@setfilename ../info/control-jp
@clear jp-draft
@node Control Structures, Variables, Evaluation, Top
@chapter 制御構造
@cindex 特殊形式、制御構造の[とくしゅけいしき、せいぎょこうぞうの]
@cindex 制御構造[せいぎょこうぞう]

Lispプログラムは式または@dfn{形式(form)}(@pxref{Forms})から成っています。
私たちは、それらを@dfn{制御構造(control structure)}で囲むことによって、
形式の実行の順番を制御することができます。制御構造とは、
囲んでいる形式を、いつ実行するか、実行するかしないか、何回
実行するかを制御する特殊形式のことです。

最も単純な実行順序は順次実行です。最初に形式@var{a}、
次に形式@var{b}というように実行します。これは関数の本体、
またはLispコードのファイルの最上位レベルに、複数の形式を連続して
記述したときの実行であって、それらの形式は記述された順番に実行されます。
私たちはこれを@dfn{テキストどおりの順序(textual order)}と呼んで
います。例えば、もし関数の本体が二つの形式@var{a}と@var{b}から
成っているなら、関数は最初に@var{a}、次に@var{b}を評価し、
@var{b}の値が関数の値になります。

明示的な制御構造は順次以外の実行順序を可能にします。

Emacs Lispは、順次実行の変種、条件分岐、繰返し、および(制御された)
ジャンプを含んだ数種類の制御構造を提供していて、そのすべてを以下に説明
します。
組込みの制御構造は、その部分形式が必ずしも評価されるわけではなく、
また、順番に評価されるわけでもないので、特殊形式になっているのです。
マクロを使って、独自の制御構造を定義することができます
(@pxref{Macros})。

@menu
* Sequencing::             テキストどおりの順序で評価。
* Conditionals::           @code{if}, @code{cond}.
* Combining Conditions::   @code{and}, @code{or}, @code{not}.
* Iteration::              @code{while} ループ。
* Nonlocal Exits::         シーケンス外シャンプ。
@end menu

@node Sequencing
@section 順次実行

形式を出現順に評価することは、ある形式から他の形式へ制御を移す方法の
なかで、もっともよく使われるものです。
関数本体のような、いくつかの文脈においては自動的にこのようになります。
その他の場所で、これを行うには制御構造の構文要素を使用しなければ
なりません。@code{progn}はLispの最も簡単な制御の構文要素です。

特殊形式@code{progn}は以下のようなものです。

@example
@group
(progn @var{a} @var{b} @var{c} @dots{})
@end group
@end example

@noindent
これは形式@var{a}, @var{b}, @var{c}などを、その順番で実行することを
意味しています。これらの形式は@code{progn}形式の本体と呼ばれます。
本体の最後の形式の値が@code{progn}全体の値になります。

@cindex 暗黙の@code{progn}[あんもくのprogn]
初期のLispでは、@code{progn}は、連続した二つ以上の形式を実行し、
その最後の値を使用するための唯一の方法でした。
しかし、プログラマは、(その時点では)ただ一つの形式だけが許されていた
関数の本体にも、
@code{progn}を使用することがしばしば必要であることに気づきました。
そこで、関数の本体に「暗黙の@code{progn}」を作りました。
その中の形式は実際の@code{progn}の本体と同様に扱われます。
他の多くの制御構造も同様に暗黙の@code{progn}を含んでいます。
結果として、@code{progn}は本来必要であるほどには使用されません。
それは@code{unwind-protect}, @code{and}, @code{or},
または@code{if} の @var{then}部分の中で最もよく使用されます。

@defspec progn forms@dots{}
この特殊形式は@var{forms}のすべてをテキストどおりの順序で評価し、
最後の形式の結果を返します。

@example
@group
(progn (print "The first form")
       (print "The second form")
       (print "The third form"))
     @print{} "The first form"
     @print{} "The second form"
     @print{} "The third form"
@result{} "The third form"
@end group
@end example
@end defspec

以下の二つの制御構造も同様に形式の並びを評価しますが、異なった値を
返します。

@defspec prog1 form1 forms@dots{}
この特殊形式は、@var{form1}と@var{forms}のすべてをテキストどおりの
順序で評価し、@var{form1}の結果を返します。

@example
@group
(prog1 (print "The first form")
       (print "The second form")
       (print "The third form"))
     @print{} "The first form"
     @print{} "The second form"
     @print{} "The third form"
@result{} "The first form"
@end group
@end example

次の例では変数 @code{x} に設定されたリストから先頭の要素を削除し、
その削除した要素の値を返しています。

@example
(prog1 (car x) (setq x (cdr x)))
@end example
@end defspec

@defspec prog2 form1 form2 forms@dots{}
この特殊形式は、@var{form1}, @var{form2}, そしてその後の @var{forms}
のすべてをテキストどおりの順序で評価し、@var{form2}の結果を返します。

@example
@group
(prog2 (print "The first form")
       (print "The second form")
       (print "The third form"))
     @print{} "The first form"
     @print{} "The second form"
     @print{} "The third form"
@result{} "The second form"
@end group
@end example
@end defspec

@node Conditionals
@section 条件分岐
@cindex 条件評価[じょうけんひょうか]

条件分岐の制御構造は選択肢の中から選び出すことをします。
Emacs Lispは、二つの条件分岐の形式を持っています。
他の言語とほとんど同じである@code{if}と、一般化されたcase文で
ある@code{cond}です。

@defspec if condition then-form else-forms@dots{}
@code{if}は@var{condition}の値を元に@var{then-form}か@var{else-forms}かを
選択します。
評価された@var{condition}が@code{nil}でないならば、@var{then-form}
が評価され、その結果が返されます。
そうでなければ、@var{else-forms}がテキストどおりの順序で評価され、
最後のものの値が返されます。
(@code{if}の@var{else}部は暗黙の@code{progn}の例です。
@pxref{Sequencing})

@var{condition}が値@code{nil}を持ち、@var{else-forms}が与えられて
いなければ、@code{if}は@code{nil}を返します。

@code{if}は選択されない枝はまったく評価されない
(無視される)ので、特殊形式になっています。
したがって、以下の例で@code{print}は決して呼ばれないので@code{true}
は印字されません。

@example
@group
(if nil 
    (print 'true) 
  'very-false)
@result{} very-false
@end group
@end example
@end defspec

@defspec cond clause@dots{}
@code{cond}は任意個の選択肢から選択します。
@code{cond}の個々の@var{clause}はリストでなければなりません。
このリストの@sc{car}は@var{condition}です。
残りの要素は(もしあれば)@var{body-forms}です。
したがって句(clause)は次のようになります。

@example
(@var{condition} @var{body-forms}@dots{})
@end example

@code{cond}は個々の句の@var{condition}を評価していくことによって、
その句の並びをテキストどおりの順序で試します。
@var{condition}の値が@code{nil}でなければ、その句は「成功」します。
その場合、@code{cond} はその@var{body-forms}を評価し、
@var{body-forms}の最後の値が@code{cond}の値となります。
残りの句は無視されます。

@var{condition}の値が@code{nil}ならば、その句は「失敗」し、
@code{cond}は次の句に制御を移し、その @var{condition}を試していきます。

すべての@var{condition}が@code{nil}に評価された場合、すなわち、
すべての句が失敗した場合、@code{cond}は@code{nil}を返します。

句は次のようになっているかもしれません。

@example
(@var{condition})
@end example

@noindent
その場合、@var{condition}のテスト結果が@code{nil}でなければ、
@var{condition}の値が@code{cond}形式の値になります。

以下の例では四つの句を持っていて、それぞれ@code{x}の値が
数値、文字列、バッファ、シンボルのどれかであるかをテスト
します。

@example
@group
(cond ((numberp x) x)
      ((stringp x) x)
      ((bufferp x)
       (setq temporary-hack x) ; @r{一つの句に}
       (buffer-name x))        ; @r{複数の body-forms}
      ((symbolp x) (symbol-value x)))
@end group
@end example

最後の句より前の句がどれも成功しなかった場合には、
その最後の句を実行したいということがよくあります。
これを行うために私たちは次のように最後の句の@var{condition}と
して@code{t}を使用します。@code{(t @var{body-forms})}。
形式@code{t}は@code{t}に評価され、決して@code{nil}にはならず、
したがって、この句は決して失敗せず、最悪でもそこには到達する@code{cond}
が提供されます。

例えば、

@example
@group
(cond ((eq a 'hack) 'foo)
      (t "default"))
@result{} "default"
@end group
@end example

@noindent
この式は@code{a}の値が@code{hack}ならば@code{foo}を返し、
そうでなければ文字列@code{"default"}を返す@code{cond}です。
@end defspec

あらゆる条件分岐の構造は@code{cond}でも@code{if}でも表現する
ことができます。したがって、どちらを使うかの選択はスタイルの問題です。
例えば:

@example
@group
(if @var{a} @var{b} @var{c})
@equiv{}
(cond (@var{a} @var{b}) (t @var{c}))
@end group
@end example

@node Combining Conditions
@section 条件を結合するための構文要素

この節では複雑な条件を表現するために@code{if}
や@code{cond}とともによく使用される三つの構文要素を説明します。
構文要素@code{and}と@code{or}は、ある種の複合した条件を
組み合わせるものとして別個に使用されることもあります。

@defun not condition
この関数は@var{condition}が偽であるかをテストします。
@var{condition}が@code{nil}であれば@code{t}を返し、
そうでなければ@code{nil}を返します。
関数@code{not}は@code{null}と同一ですが、
空リストのテストには@code{null}の方を使用することを私たちは勧めます。
@end defun

@defspec and conditions@dots{}
特殊形式@code{and}は、すべての@var{conditions}が真であるかを
テストします。それは@var{conditions}を書かれた順序で一つずつ
評価していくことによって行なわれます。

@var{conditions}のうちのどれかが@code{nil}に評価されれば、
残りの@var{conditions}がどうであろうとも@code{and}の
結果は@code{nil}になるはずです。だから、
@code{and}は残りの@var{conditions}を無視して、
ただちに帰ります。

すべての@var{conditions}が@code{nil}でなければ、その最後のものの
値が形式@code{and}の値になります。

以下に例をあげます。最初の条件は整数1(@code{nil}ではない)を返します。
同様に、2番目の条件は整数2(@code{nil} ではない)を返します。
3番目の条件は@code{nil}であり、残りの条件は決して評価されません。

@example
@group
(and (print 1) (print 2) nil (print 3))
     @print{} 1
     @print{} 2
@result{} nil
@end group
@end example

以下は@code{and}を使用した、より現実的な例です。

@example
@group
(if (and (consp foo) (eq (car foo) 'x))
    (message "foo は x で始まるリスト"))
@end group
@end example

@noindent
@code{(consp foo)}が@code{nil}を返すのであれば、
@code{(car foo)}は実行されないことに注意してください。
これによってエラーが回避されます。

@code{and}は、@code{if}または@code{cond}で表現することができます。例えば:
@example
@group
(and @var{arg1} @var{arg2} @var{arg3})
@equiv{}
(if @var{arg1} (if @var{arg2} @var{arg3}))
@equiv{}
(cond (@var{arg1} (cond (@var{arg2} @var{arg3}))))
@end group
@end example
@end defspec

@defspec or conditions@dots{}
特殊形式@code{or}は少なくとも@var{conditions}の一つが真で
あるかをテストします。それは @var{conditions}を書かれた順序で一つずつ
評価していくことによって行なわれます。

@var{conditions}のうちのどれかが@code{nil}でないものに評価されれば、
@code{or}の結果は@code{nil}以外になるはずです。
それなので、@code{or}は残りの@var{conditions}を無視して、
ただちに帰ります。その返す値は返却の直前に評価された条件
の@code{nil}でない値です。

すべての@var{conditions}が@code{nil}であれば、@code{or}は@code{nil}を
返します。

例えば、以下の式は@code{x}が0または@code{nil}のどちらかである
かをテストします。

@example
(or (eq x nil) (eq x 0))
@end example

構文要素@code{and}のように、@code{or}は@code{cond}で書き表すことが
できます。例えば:

@example
@group
(or @var{arg1} @var{arg2} @var{arg3})
@equiv{}
(cond (@var{arg1})
      (@var{arg2})
      (@var{arg3}))
@end group
@end example

@code{if}を使っても@code{or}とほとんど同じものを書き表すことが
できますが、完全ではありません。

@example
@group
(if @var{arg1} @var{arg1}
  (if @var{arg2} @var{arg2} 
    @var{arg3}))
@end group
@end example

@noindent
これは@var{arg1}または@var{arg2}を2回評価するので、
完全には等しくありません。
一方、@code{(or @var{arg1} @var{arg2} @var{arg3})}では、
何度も評価されることは決してありません。
@end defspec

@node Iteration
@section 繰り返し
@cindex 繰り返し[くりかえし]

繰り返しはプログラムの一部を反復して実行することを意味します。
例えば、あなたはリストの個々の要素について一度ずつ、
または0から@var{n}までの個々の整数について一度ずつ、
ある計算を行ないたいとします。
あなたは特殊形式@code{while}を使用してEmacs Lispでこれを
行なうことができます。

@defspec while condition forms@dots{}
@code{while}は最初に@var{condition}を評価します。
その結果が@code{nil}でなければ、テキストどおりの順序で@var{forms}を
評価します。そして、@var{condition}を再評価し、その結果が @code{nil}
でなければ@var{forms}を再び評価します。
この処理は@var{condition}が@code{nil}に評価されるまで繰り返します。

繰り返しの回数には制限がありません。その繰り返しは、@var{condition}が@code{nil}
に評価されるか、エラーまたは@code{throw}による脱出(@pxref{Nonlocal Exits})
が発生するまで継続します。

形式@code{while}の値は常に@code{nil}です。

@example
@group
(setq num 0)
     @result{} 0
@end group
@group
(while (< num 4)
  (princ (format "Iteration %d." num))
  (setq num (1+ num)))
     @print{} Iteration 0.
     @print{} Iteration 1.
     @print{} Iteration 2.
     @print{} Iteration 3.
     @result{} nil
@end group
@end example

個々の繰り返しで終了テストの直前に毎回何かを実行したいならば、
以下に示すように@code{while}の最初の引数として@code{progn}を置き、
その中に、終了テストと一緒に置きます。

@example
@group
(while (progn
         (forward-line 1)
         (not (looking-at "^$"))))
@end group
@end example

@noindent
これは前方に1ライン移動し、空行に達するまで行移動を継続します。
@code{while}が本体を持たず、終了テストだけ(ポイントの移動という
実際の処理も行うが)という点で、まれなものです。
@end defspec

@node Nonlocal Exits
@section 非局所脱出
@cindex nonlocal exit
@cindex 非局所脱出[ひきょくしょだっしゅつ]

@dfn{非局所脱出(nonlocal exit)}はプログラム中のある位置から、
別の離れた位置への制御の移行です。非局所脱出はEmacs Lispでは、エラーの
結果として生じることがあります。また、明示的な制御のもとで、それを使用する
こともできます。非局所脱出は脱出しようとしている構文要素にある全ての
変数の束縛を解きます。


@menu
* Catch and Throw::     プログラム自身の目的のための非局所脱出。
* Examples of Catch::   そのような非局所脱出をどのように記述するかの例。
* Errors::              エラーはどのように伝えられ、ハンドルされるか。
* Cleanups::            エラーが起きた際のクリーンアップ形式を実行する
                        ための配置。
@end menu

@node Catch and Throw
@subsection 明示的な非局所脱出: @code{catch} と @code{throw}

たいていの制御構造は構造自身内での制御の流れにのみ影響します。
関数@code{throw}は、この通常のプログラム実行の規則の例外です。
それは要求により非局所脱出を実行します
(他の例外もありますが、それはエラーをハンドルするだけのためのものです)。
@code{throw}は@code{catch}の内側で使用され、その@code{catch}に
飛びます。例えば:

@example
@group
(catch 'foo
  (progn
    @dots{}
    (throw 'foo t)
    @dots{}))
@end group
@end example

@noindent
@code{throw}は該当する@code{catch}の直後に制御を移します
(該当する@code{catch}から直ちにリターンする)。
@code{throw}以降のコードは実行されません。
@code{throw}の2番目の引数は@code{catch}の戻り値として使用されます。

@code{throw}と@code{catch}は最初の引数によって対応がつけられます。
@code{throw}は、最初の引数が@code{throw}で指定されたもの
と@code{eq}である@code{catch}を検索します。
したがって上記の例では、@code{throw}は、@code{foo}を指しており、
@code{catch}も同じシンボルを指定しているので、その@code{catch}が
適用されます。二つ以上の適用可能な@code{catch}がある場合は、
最も内側のものが優先されます。

@code{throw}を実行すると、対応する@code{catch}までの、
すべてのLisp構文要素(関数呼出しも含む)から脱出します。
@code{let}または関数呼出しのような束縛をつくる構文要素から
このようにして脱出した場合、
それらの構文要素が普通に終了するのと同様に、
その束縛は解除されます(@pxref{Local Variables})。
同様に、@code{throw}は@code{save-excursion} (@pxref{Excursions})に
よって保存されていたバッファとポジション、@code{save-restriction}
によって保存されていたナローイング状態、@code{save-window-excursion}
によって保存されていたウィンドウ・セレクション(@pxref{Window Configurations})
を復元します。その形式を脱出するときには、@code{unwind-protect}特殊形式
によって設定されたあらゆるクリーンアップも行ないます(@pxref{Cleanups})。

@code{throw}は、それがジャンプする先の@code{catch}がレキシカルに存在して
いることを必要としません。それは@code{catch}の中で呼び出される別の
関数からも同様に呼び出されることができます。@code{throw}が評価順で
@code{catch}の後であり、それから抜けるのが評価順で前であるかぎり、
その @code{catch} へのアクセスを持ちます。これが
エディタのコマンド・ループに戻る @code{exit-recursive-edit} 
(@pxref{Recursive Editing})のようなコマンドで@code{throw}が使用できる
理由です。

@cindex CL注意書き---Emacsでは@code{throw}のみ[CLちゅういがき---emacsではthrowのみ]
@quotation
@b{Common Lisp注意書き:} Common Lispを含む、ほとんどの他のバージョン
のLispは非順次的に制御を移す方法をいくつか持っています。例えば、
@code{return}, @code{return-from}, @code{go}があります。Emacs Lisp
は@code{throw}だけを持ちます。
@end quotation

@defspec catch tag body@dots{}
@cindex タグ、実行時スタックの[たぐ、じっこうじすたっくの]
@code{catch}は@code{throw}関数のための復帰位置を確立します。
復帰位置は@var{tag}(任意の Lisp オブジェクトを指定可能)によって
他の復帰位置と区別されます。普通は復帰位置が確立される前に、
引数@code{tag}が評価されます。

有効な復帰位置を持って、@code{catch}は、テキストどおりの順序で@var{body}
の形式を評価します。エラーまたは非局所脱出なしに、普通にその形式が
実行されるならば、@var{body}の最後の形式の値が@code{catch}から
返されます。

@code{throw}が同じ値@var{tag}を指定して@var{body}の中で行なわれる
ならば、直ちに@code{catch}を抜けます。それが返す値は
@code{throw}の2番目の引数として指定されたものです。
@end defspec

@defun throw tag value
@code{throw}の目的は前もって@code{catch}によって設定された復帰
位置に戻ることです。引数@var{tag}は、いくつかの存在する復帰位置
の中から選択するために使用されます。それは@code{catch}に指定された
値と@code{eq}にならなければなりません。複数の復帰位置が@var{tag}
と一致する場合、最も内側のものが使用されます。

引数@var{value}は、その@code{catch}から返す値として使用
されます。

@kindex no-catch
実効的にタグ@var{tag}に一致する復帰位置がない場合には、
@code{no-catch}エラーがデータ@code{(@var{tag} @var{value})}
をともなって発行されます。
@end defun

@node Examples of Catch
@subsection @code{catch}と@code{throw}の例

@code{catch}と@code{throw}を使用する一つの方法は2重に入れ子に
なったループから抜けることです。(たいていの言語では、これは ``go to''
で行なわれます。) 以下は @var{i} と @var{j} をそれぞれ 0
から 9 まで値を変えていきながら @code{(foo @var{i} @var{j})} を
計算します。

@example
@group
(defun search-foo ()
  (catch 'loop
    (let ((i 0))
      (while (< i 10)
        (let ((j 0))
          (while (< j 10)
            (if (foo i j)
                (throw 'loop (list i j)))
            (setq j (1+ j))))
        (setq i (1+ i))))))
@end group
@end example

@noindent
@code{foo}が仮に@code{nil}でない値を返したならば、
直ちに中断して、@var{i}と@var{j}のリストを返します。
@code{foo}が常に@code{nil}を返すならば、
@code{catch} は普通に復帰し、その値は @code{nil} になります
(それが @code{while} の結果であるので)。

次に、二つのトリッキーな例を示します。
それらは、同時に二つの復帰位置を示していますが、わずかに異なっています。

最初のものには同じタグ@code{hack}をもつ二つの復帰位置があります。

@example
@group
(defun catch2 (tag)
  (catch tag
    (throw 'hack 'yes)))
@result{} catch2
@end group

@group
(catch 'hack 
  (print (catch2 'hack))
  'no)
@print{} yes
@result{} no
@end group
@end example

@noindent
両方の復帰位置が@code{throw}と一致するタグを持っているので、
それは内側の@code{catch2}で設定されたものに行きます。
したがって@code{catch2}は普通に値@code{yes}を返し、この値が
印字されます。最後には外側の@code{catch}の2番目の形式
(@code{'no})が評価され、外側の@code{catch}から復帰します。

ここで、@code{catch2} に与えれている引数を変えてみましょう。

@example
@group
(defun catch2 (tag)
  (catch tag
    (throw 'hack 'yes)))
@result{} catch2
@end group

@group
(catch 'hack
  (print (catch2 'quux))
  'no)
@result{} yes
@end group
@end example

@noindent
この例も二つの復帰位置を持ちますが、外側のものだけがタグ@code{hack}
を持ちます。内側のものは、その代わりにタグ@code{quux}を持っています。
したがって、@code{throw}により、外側の@code{catch}が値@code{yes}を返
します。関数@code{print}は決して呼び出されず、本体の
形式@code{'no}は決して評価されません。

@node Errors
@subsection エラー
@cindex error
@cindex エラー[えらー]

Emacs Lispは何かの理由によって評価できない形式を評価しようとした場合、
@dfn{エラー(error)}を@dfn{発行(signal)}します。

エラーが発行された場合、Emacsのデフォルトの反応はエラーメッセージを
印字し、現在のコマンドの実行を終了することです。
これは、ほとんどの場合適切なものです。
例えば、バッファの最後で@kbd{C-f}をタイプするような場合です。

複雑なプログラムでは、単純な終了が望むものでは
ないかもしれません。例えば、そのプログラムはデータ構造の一時的な変更を行って
いるかもしれないし、プログラムが終了する前に消去されるべき、
一時的なバッファを作成しているかもしれません。そのような場合には
エラーの場合に評価される@dfn{クリーンアップ式(cleanup expression)}を設定する
@code{unwind-protect} を使用します(@pxref{Cleanups})。ときには
サブルーチンでエラーがあっても、実行の継続を
望むかもしれません。このような場合には、エラーの場合に制御を回復するための
@dfn{エラー・ハンドラ(error handler)}を設定する @code{condition-case} を
使用します。

プログラムのある場所から別の場所に制御を移すためにエラーのハンドルを
使用する、という誘惑には抵抗してください。その代わりには@code{catch}
と@code{throw}を使用してください。@xref{Catch and Throw}。

@menu
* Signaling Errors::      エラーを報告する方法。
* Processing of Errors::  エラーを報告したときに Emacs が行うこと。
* Handling Errors::       エラーの捕捉と実行の継続の方法。
* Error Symbols::         捕らえたエラーを分類する方法。
@end menu

@node Signaling Errors
@subsubsection エラーを発行する方法
@cindex 発行、エラーの[はっこう、えらーの]

ほとんどのエラーは、他の目的で呼び出しているLisp プリミティブ
(例えば、整数の@sc{car}を取ろうとしたり、バッファの最後で前方に
移動しようとすること)によって「自動的に」発行されます。
一方、関数@code{error}と@code{signal}によって、明示的にエラーを発行する
こともできます。

とりやめ(ユーザが @kbd{C-g}をタイプしたときに起きること)は
エラーとは考えられませんが、ほとんどエラーと同様にハンドル
されます。@xref{Quitting}。

@defun error format-string &rest args
この関数は、@code{format} (@pxref{String Conversion})を
@var{format-string}と@var{args}に適用し
エラー・メッセージを作り、エラーを発行します。

以下は@code{error}の典型的な使用例を示しています。

@example
@group
(error "You have committed an error.  
        Try something else.")
     @error{} You have committed an error.  
        Try something else.
@end group

@group
(error "You have committed %d errors." 10)
     @error{} You have committed 10 errors.  
@end group
@end example

@code{error}は、二つの引数(エラー・シンボル@code{error}と@code{format}
によって返される文字列を含んだリスト)とともに@code{signal}を呼び出す
ことをします。

文字列をエラー・メッセージとしてそのまま使用したい場合、
@code{(error @var{string})}とだけ書いてはいけません。@var{string}が
@samp{%} を含んでいる場合、それは整形指定として解釈され、不正な結果
になってしまいます。その代わりに、@code{(error "%s" @var{string})}
としてください。
@end defun

@defun signal error-symbol data
この関数は@var{error-symbol}によって名づけられたエラーを発行します。
引数@var{data}はエラーの状況に関連する追加のLispオブジェクトです。

引数@var{error-symbol}は、@dfn{エラー・シンボル(error symbol)}
(値が条件名のリストである属性@code{error-conditions}をもつシンボル)で
なければなりません。これが、Emacs Lispが種々のエラーを分類する
やり方です。

@var{data}中のオブジェクトの数と意味は@var{error-symbol}に依存
します。例えば、@code{wrong-type-arg}エラーでは、リストに二つの
オブジェクトを入れます。期待されている型を記述する述語と、
その型との適合に失敗したオブジェクトです。エラー・シンボルの説明は、
@xref{Error Symbols}。

@var{error-symbol}と@var{data}の両方を、エラーをハンドルする任意の
エラー・ハンドラは利用できます。@code{condition-case}はローカル変数に
形式@code{(@var{error-symbol} . @var{data})}のリストを束縛します
(@pxref{Handling Errors})。エラーがハンドルされなければ、これら二つの
値がエラー・メッセージの印字に使用されます。

関数@code{signal}から戻ることはありません。(しかし、古いバージョンのEmacsでは
戻れることもありました)。

@smallexample
@group
(signal 'wrong-number-of-arguments '(x y))
     @error{} Wrong number of arguments: x, y
@end group

@group
(signal 'no-such-error '("My unknown error condition."))
     @error{} peculiar error: "My unknown error condition."
@end group
@end smallexample
@end defun

@cindex CL注意書き---continuable エラーはない[CLちゅういがき---continuableえらーはない]
@quotation
@b{Common Lisp注意書き:} Emacs LispにはCommon Lispのcontinuableエラー
の概念に相当するものはありません。
@end quotation

@node Processing of Errors
@subsubsection Emacsがエラーをハンドルする方法

エラーが発行された場合、@code{signal}は、そのエラーについて有効な
@dfn{ハンドラ(handler)}を探します。ハンドラは、Lispプログラムの一部で
エラーが起きた場合に実行されるように指定されたLisp式のならびです。
そのエラーが適切なハンドラを持っていれば、そのハンドラが実行され、
そのハンドラの後から、制御が再開されます。そのハンドラは、それを、
設定された@code{condition-case}の環境で実行されます。
@code{condition-case}で呼ばれるすべての関数は、すでに脱出しているので、
ハンドラはそれらに戻れません。

そのエラーに対して適切なハンドラがなければ、現在のコマンドは終了させられ、
制御はエディタのコマンド・ループに戻ります。コマンド・ループには、
あらゆる種類のエラーを扱う暗黙のハンドラがあるからです。
コマンド・ループのハンドラはそのエラー・シンボルと、エラー・メッセージ
の印字に関連したデータを使用します。

@cindex @code{debug-on-error}の使用[debug-on-errorのしよう]
明示的なハンドラを持たないエラーはLispデバッガを呼び出すことが
できます。デバッガは変数@code{debug-on-error} (@pxref{Error Debugging})
が@code{nil}でない場合に有効にされます。エラー・ハンドラとは違い、
デバッガはエラーの環境で動作するので、あなたはエラーの時点
での変数の値を正確に調べることができます。

@node Handling Errors
@subsubsection エラーをハンドルするコードの記述
@cindex error handler
@cindex エラー・ハンドラ[えらー・はんどら]
@cindex ハンドル、エラーの[しょり、えらーの]

エラーを発行することの通常の効果は動作しているコマンドを終了し、
直ちにEmacsエディタのコマンド・ループに戻ることです。
特殊形式@code{condition-case}でエラー・ハンドラを設定すると、
プログラムのある部分で起こるエラーを捕捉するようにすることが
できます。以下に簡単な例を示します。

@example
@group
(condition-case nil
    (delete-file filename)
  (error nil))
@end group
@end example

@noindent
これは、@var{filename}という名前のファイルを消去し、
どんなエラーでもそれが起きたときには捕捉し、@code{nil}を返します。

@code{condition-case}の2番目の引数は@dfn{保護形式(protected form)}です
(先の例での保護形式は@code{delete-file}を呼び出すことです)。
この形式の実行が始まるときにエラー・ハンドラが有効になり、
この形式が戻るときに無効化されます。それは介在する時間のすべてにおいて
有効状態にあります。特に、この形式、そのサブルーチン、その他
によって呼び出される関数の実行中には有効状態にあります。
厳密な話、エラーは保護形式によって呼び出されるLispプリミティブ
(@code{signal}と@code{error}を含む)によって発行されるのであって、
保護形式自身によって発行されるものではないので、これはよいことです。

引数の中で、保護形式の後にはハンドラが続きます。個々のハンドラには、
ハンドルするエラーを指定する、一つ以上の(シンボルである)
@dfn{状態名(condition name)}のリストを置きます。エラーを発行するときに
指定するエラーシンボルも、状態名のリストを定義します。それらが共通の
状態名をもつならば、そのハンドラがエラーに適合します。先の例では
一つのハンドラがあり、それはすべてのエラーをカバーする一つの
状態名@code{error}を指定しています。

適用可能なハンドラの探索は最も最近に設定されたハンドラから始め、すべての
設定されたハンドラをチェックします。したがって、二重にネストしている
@code{condition-case}形式が同じエラーをハンドルするようになっている
場合には、二つのうちの内側のものが実際にそれをハンドルすることになります。

エラーがハンドルされるときには、制御がハンドラに渡ります。これが起こる前に、
Emacsは抜けようとしている束縛構文要素によって束縛されている全ての変数の束縛を
解除し、抜けたすべての@code{unwind-protect}形式のクリーンアップを実行
します。いったん、制御がハンドラに到達すると、そのハンドラの本体が実行
されます。

ハンドラの本体の実行の後、実行は@code{condition-case}形式から
戻ることで続行します。保護形式はハンドラの実行前に完全に抜けて
いるので、ハンドラはエラー時点の実行を再開することはできず、
保護形式で束縛していた変数を調べることもできません。行えることの
すべてはクリーンアップと続行です。

@code{condition-case} は、@code{insert-file-contents} の呼び出しで
ファイルのオープンに失敗するといった、予想できるエラーを捕捉するのに
よく使用されます。また、プログラムがユーザから読み込んだ式を評価する
ときに起きるような、まったく予測不可能なエラーを捕捉するのにも
使用されます。

エラーの発行とハンドルは、@code{throw}と@code{catch}と類似している点が
ありますが、まったく異なった機能です。エラーは@code{catch}で
捕まえることはできませんし、@code{throw}はエラー・ハンドラでハンドルする
ことができません(しかし、ふさわしい@code{catch}がない@code{throw}を
使うと、ハンドルできるエラーを発行します)。

@defspec condition-case var protected-form handlers@dots{}
この特殊形式は、@var{protected-form}の実行の間に有効になる
エラー・ハンドラ@var{handlers}を設定します。@var{protected-form}が
エラーなしで実行されると、その戻り値が、@code{condition-case}形式の
値になります。この場合、@code{condition-case}はまったく効果を持ちません。
@var{protected-form}の実行中にエラーが発生した場合、
@code{condition-case}は違う動作を行ないます。

@var{handlers}のそれぞれは、形式@code{(@var{conditions} @var{body}@dots{})}
のリストです。@var{conditions}はハンドルされるエラーの状態名、
または状態名のリストです。@var{body}は、このハンドラがエラーをハンドル
するときに実行される一つ以上のLisp式です。以下はハンドラの例です。

@smallexample
@group
(error nil)

(arith-error (message "Division by zero"))

((arith-error file-error)
 (message
  "Either division by zero or failure to open a file"))
@end group
@end smallexample

起こる個々のエラーは、それが何の種類のエラーであるかを示す
@dfn{エラー・シンボル(error symbol)}を持ちます。そのシンボルの
@code{error-conditions}属性は状態名のリストです(@pxref{Error Symbols})。
Emacsは、これらの状態名のうちの一つ以上を指定するハンドラをすべての
有効な@code{condition-case}形式から検索します。最も内側で一致する
@code{condition-case}がエラーをハンドルします。この@code{condition-case}に
おいて、最初の適用可能なハンドラがエラーをハンドルします。

ハンドラの本体の実行の後、@code{condition-case}からは普通に戻り、
ハンドラの本体の中で最後の形式の値を、その全体の値として使用します。

引数@var{var}は変数です。@code{condition-case}は@var{protected-form}
を実行しているとき、この変数を束縛せず、エラーをハンドルするときにのみ
束縛します。その時点では変数@var{var}を形式
@code{(@var{error-symbol} . @var{data})}に局所的に束縛し、エラーの詳細
を与えます。ハンドラは何を行うかを決定するために、このリストを
参照することができます。例えば、エラーが、ファイルのオープンに失敗
したというものであれば、ファイル名は@var{data}の2番目の要素
(@var{var} の3番目の要素)になっています。

@var{var}が@code{nil}ならば、変数を束縛する手段はありません。
ハンドラは、エラー・シンボルおよび関連するデータを使えません。
@end defspec

@cindex @code{arith-error}の例[arith-errorのれい]
以下は0による除算から起きるエラーをハンドルするために@code{condition-case}
を使用した例です。ハンドラは警告メッセージを印字し、非常に大きな数を
返します。

@smallexample
@group
(defun safe-divide (dividend divisor)
  (condition-case err                
      ;; @r{保護形式。}
      (/ dividend divisor)              
    ;; @r{ハンドラ。}
    (arith-error                        ; @r{状態。}
     (princ (format "Arithmetic error: %s" err))
     1000000)))
@result{} safe-divide
@end group

@group
(safe-divide 5 0)
     @print{} Arithmetic error: (arith-error)
@result{} 1000000
@end group
@end smallexample

@noindent
ハンドラは状態名@code{arith-error}を指定しているので、0による除算だけ
をハンドルします。他の種類のエラーはハンドルされません。少なくとも、
この@code{condition-case}によってはハンドルされません。したがって、

@smallexample
@group
(safe-divide nil 3)
     @error{} Wrong type argument: integer-or-marker-p, nil
@end group
@end smallexample

以下は、あらゆる種類のエラー(@code{error}で発行されたものも含む)を
捕らえる@code{condition-case}です。

@smallexample
@group
(setq baz 34)
     @result{} 34
@end group

@group
(condition-case err
    (if (eq baz 35)
        t
      ;; @r{これは関数 @code{error} の呼び出しです。}
      (error "Rats!  The variable %s was %s, not 35" 'baz baz))
  ;; @r{これはハンドラです; 形式ではありません。}
  (error (princ (format "The error was: %s" err)) 
         2))
@print{} The error was: (error "Rats!  The variable baz was 34, not 35")
@result{} 2
@end group
@end smallexample

@node Error Symbols
@subsubsection エラー・シンボルと条件名
@cindex error symbol
@cindex condition name
@cindex エラー・シンボル[えらー・しんぼる]
@cindex エラー名[えらーめい]
@cindex 状態名[じょうたいめい]
@cindex ユーザ定義のエラー[ゆーざていぎのえらー]
@kindex error-conditions

エラーを発行するときには、あなたが念頭に置いているエラーの種類を
示す@dfn{エラー・シンボル(error symbol)}を指定します。個々のエラーは、
それを分類するために、唯一無二のエラー・シンボルを持っています。これは
Emacs Lisp言語で定義された、最も優れたエラーの分類法です。

この狭い分類法は
@dfn{状態名(condition name)}で識別される@dfn{エラー状態(error condition)}
と呼ばれる、より幅のある種別の階層にグループ化されています。そのような
種別の中で最も狭いものが、エラー・シンボルそのものです。個々の
エラー・シンボルは状態名でもあります。より広い種別の状態名もあり、
それはあらゆる種類のエラーをとる状態名@code{error}にまで至ります。
したがって、個々のエラーは一つ以上の状態名を持っています。
すなわち、@code{error}、@code{error}からより明瞭に
する場合のエラー・シンボル、そして場合によっては中間の分類によるもの。

シンボルがエラー・シンボルであるためには、状態名のリストを
与える@code{error-conditions}属性を持たなければなりません。
このリストは、その種類のエラーが属する状態を定義します
(エラー・シンボル自身とシンボル@code{error}は、常にこのリストの
メンバーであるべきです)。したがって、状態名の階層は
エラー・シンボルの@code{error-conditions}属性によって定義されます。

@code{error-conditions}リストに加えて、エラー・シンボルは
@code{error-message}属性をもつべきであり、その値は、
そのエラーが発行されたけれどもハンドルされない場合に印字される文字列です。
@code{error-message}属性が存在するけれども文字列でない場合には
エラー・メッセージ@samp{peculiar error}が使用されます。
@cindex peculiar error

以下はエラー・シンボル@code{new-error}を定義する方法を示しています。

@example
@group
(put 'new-error
     'error-conditions
     '(error my-own-errors new-error))       
@result{} (error my-own-errors new-error)
@end group
@group
(put 'new-error 'error-message "A new error")
@result{} "A new error"
@end group
@end example

@noindent
このエラーは三つの状態名を持っています。
最も狭い分類である@code{new-error}、
それよりは広い分類であろう@code{my-own-errors}、そして
すべてに渡る最も広いものである@code{error}です。

エラーの文字列は英大文字で始まるべきですが、ピリオドで終るべきでは
ありません。これはEmacsの他のものとの一貫性のためです。
 
もちろんEmacsは、それ自身では@code{new-error}を発行しません。
自分のコードで@code{signal} (@pxref{Signaling Errors})を
明示的に呼び出すことによってのみ、これを行うことができます。

@example
@group
(signal 'new-error '(x y))
     @error{} A new error: x, y
@end group
@end example

このエラーは三つの状態名のうちのどれかでハンドルすることができます。
以下の例は、@code{new-error}と@code{my-own-errors}に分類される
任意のエラーをハンドルします。

@example
@group
(condition-case foo
    (bar nil t)
  (my-own-errors nil))
@end group
@end example

エラーを分類する有意義な方法は、状態名(エラーをハンドラと一致させる
ために使用する名前)によることです。エラーシンボルは意図した
エラー・メッセージと状態名のリストとを指定するのに
便利な方法としてのみ役立ちます。一つのエラー・シンボルではなく、
状態名のリストを@code{signal}に与えるのは面倒なことです。

逆に、状態名ではなく、エラー・シンボルを使用することは
@code{condition-case}の能力を明らかに減少させます。
状態名は、あなたがエラー・ハンドラを書くときに、普遍性のあるさまざまなレベルに
エラーを分類することを可能にします。エラー・シンボル単独で使用することは
最も狭いレベルの分類以外をすべてふるい落します。

すべての標準のエラー・シンボルとその状態の一覧は、@xref{Standard Errors}。

@node Cleanups
@subsection 非局所脱出のクリーンアップ

構文要素@code{unwind-protect}は、一時的に、あるデータ構造を一貫性のない
状態に置くときには常に必須となります。つまり、エラーまたはthrow
の場合に、データが一貫していることを保証することができます。

@defspec unwind-protect body cleanup-forms@dots{}
@cindex cleanup form
@cindex protected form
@cindex クリーンアップ形式[くりーんあっぷけいしき]
@cindex 保護形式[ほごけいしき]
@cindex エラーのクリーンアップ[えらーのくりーんあっぷ]
@cindex unwinding
@code{unwind-protect}は、
制御が@var{body}から離れた場合、そこでどのようなことが起ころうとも
@var{cleanup-forms}が評価される、という保証の上で@var{body}を実行
します。@var{body}が普通に完了する場合、
@code{unwind-protect}の外に@code{throw}が実行される場合、
エラーが起きた場合など、あらゆる場合に@var{cleanup-forms}が
評価されます。

@var{body}形式が普通に終る場合、@code{unwind-protect}は
@var{cleanup-forms}を評価した後に、最後の@var{body}形式の値を
返します。@var{body}形式が終了しなかった場合、
@code{unwind-protect}は普通の感覚においては何も値を返しません。

実際には@var{body}だけが@code{unwind-protect}によって保護されます。
@var{cleanup-forms}自身のどこかで、非局所的な脱出が起きた場合(例えば、
@code{throw}またはエラー)、@code{unwind-protect}は、その後の部分の
評価を保証@emph{しません}。
@var{cleanup-forms}のうちの一つの失敗に、問題を引き起こす可能性が
ある場合には、その形式を別の@code{unwind-protect}で保護してください。

現在有効な@code{unwind-protect}形式の個数は、ローカル変数の束縛の数とともに、
上限@code{max-specpdl-size}に対してカウントされます
(@pxref{Local Variables})。
@end defspec

例えば、以下では一時的な利用のために不可視のバッファを作り、終る前に
かならずそれを削除するようにしています。

@smallexample
@group
(save-excursion
  (let ((buffer (get-buffer-create " *temp*")))
    (set-buffer buffer)
    (unwind-protect
        @var{body}
      (kill-buffer buffer))))
@end group
@end smallexample

@noindent
@code{(kill-buffer (current-buffer))}と書き、変数@code{buffer}なし
ですますことができると考えるかもしれません。しかし、
違うバッファに切り替わった後に@var{body}がエラーを受け取ることが
起こり得るならば、上に示した方法の方が安全です!  (代わりに、
本体のまわりに別の@code{save-excursion}を書き、一時的なバッファ
が、それを削除するときにカレントになることを保証するようにすることが
できます。)

@findex ftp-login
以下はファイル@file{ftp.el}から取ってきた実際の例です。
それはリモート・マシンへの接続を設定しようとするプロセスを
作ります(@pxref{Processes})。関数@code{ftp-login}は、
関数の作者が予期できない多くの問題に直面する確率が高いので、
失敗の場合にプロセスの消去を保証する形式で保護します。
そうしなければ、Emacsは無駄なサブプロセスで満たされるかも
しれません。

@smallexample
@group
(let ((win nil))
  (unwind-protect
      (progn
        (setq process (ftp-setup-buffer host file))
        (if (setq win (ftp-login process host user password))
            (message "Logged in")
          (error "Ftp login failed")))
    (or win (and process (delete-process process)))))
@end group
@end smallexample

この例は実際には小さなバグを持っています。ユーザがとりやめようと
して@kbd{C-g}をタイプし、関数@code{ftp-setup-buffer}から戻った
直後で、変数@code{process}が設定される前に中断が起きると、
そのプロセスは削除されません。このバグを修正する容易な方法は
ありませんが、とにかく、それは非常にありそうもないことです。

以下は一時的なバッファを必ず削除するようにするために@code{unwind-protect}
を使用する別の例です。この例では@code{unwind-protect}によって返却
される値が使用されています。

@smallexample
(defun shell-command-string (cmd)
  "Return the output of the shell command CMD, as a string."
  (save-excursion
    (set-buffer (generate-new-buffer " OS*cmd"))
    (shell-command cmd t)
    (unwind-protect
        (buffer-string)
      (kill-buffer (current-buffer)))))
@end smallexample
