一つには、うっかり実行してしまっても心配しなくて済むようにするためです。これから、エラーメッセージを生成するコマンドをLispインタプリタに発行します。これは無害な操作であり、実際、意図的にエラーメッセージを生成しようとすることもよくあります。専門用語を理解すれば、エラーメッセージは有益な情報となり得ます。「エラー」メッセージと呼ぶのではなく、「ヘルプ」メッセージと呼ぶべきでしょう。それらは見知らぬ国を旅する者にとっての道標のようなものです。解読するのは難しいかもしれませんが、一度理解すれば、進むべき方向を示してくれます。
このエラーメッセージは、GNU Emacs内蔵のデバッガによって生成されています。デバッガに入ります。q と入力するとデバッガを終了できます。
ここでは、クォートで囲まれておらず、かつ先頭要素に意味のあるコマンドが含まれていないリストを評価します。以下は、先ほど使用したものとほぼ同一ですが、先頭のシングルクォートがないリストです。リストの直後にカーソルを置き、C-x C-e と入力してください:
(this is an unquoted list)
*Backtrace* ウィンドウが開き、その中に以下が表示されるはずです:
---------- Buffer: *Backtrace* ---------- Debugger entered--Lisp error: (void-function this) (this is an unquoted list) (progn (this is an unquoted list)) eval((progn (this is an unquoted list)) t) elisp--eval-last-sexp(nil) #f(compiled-function () #<bytecode ...>)() handler-bind-1(#f(compiled-function () #<bytecode ...>) (error) eval-expression--debug) eval-last-sexp(nil) funcall-interactively(eval-last-sexp nil) call-interactively(eval-last-sexp nil nil) command-execute(eval-last-sexp) ---------- Buffer: *Backtrace* ----------
カーソルはこのウィンドウ内に表示されます(表示されるまで数秒かかる場合があります)。デバッガを終了してデバッガウィンドウを閉じるには、以下を入力してください:
q
デバッガから抜け出せるという自信が持てるよう、今すぐ q と入力してください。その後、再度入るために C-x C-e と入力してください。
既知の情報からすれば、このエラーメッセージはほぼ読み取れます。
*Backtrace* バッファを下から上に向かって読み進めると、Emacs
がどのような処理を行ったかが分かります。C-x C-e と入力した際、コマンド eval-last-sexp をインタラクティブに呼び出しました。eval は「evaluate」の略であり、sexp
は「symbolic expression」の略です。このコマンドは「最後のシンボリック式を評価する」という意味で、カーソルの直前にある式を指します。
上記の各行は、Lispインタプリタが次に何を評価したかを示しています。直近の処理が一番上に表示されます。このバッファは、Emacsを遡って追跡できるため、*Backtrace*バッファと呼ばれています。
*Backtrace*バッファの先頭に、次の行があります:
Debugger entered--Lisp error: (void-function this)
Lispインタプリタは、リストの最初のアトムである単語 ‘this’ を評価しようとしました。この動作によって、エラーメッセージ ‘void-function this’ が生成されました。
メッセージには「void-function」と「this」という単語が含まれています。
「function」という単語は、以前に一度登場しました。これは非常に重要な単語です。ここでの目的においては、関数とは、コンピュータに何らかの動作を指示する一連の命令であると定義できます。
これで、エラーメッセージ「void-function this」の意味が分かり始めてきました。この関数(つまり「this」という単語)には、コンピュータが実行すべき命令セットの定義が存在しないのです。
少々奇妙な単語である ‘void-function’ は、Emacs Lisp の実装方式、すなわちシンボルに関数定義が紐付けられていない場合、命令が格納されるべき場所が空になるという仕組みをカバーするために設計されています。
一方で、2 + 2 の計算を正常に行えたため、(+ 2 2) を評価することで、記号 + にはコンピュータが従うべき一連の命令が存在し、それらの命令は + に続く数値を加算するものでなければならないと推論できる。
このような場合に、Emacsがデバッガに入るのを防ぐことが可能です。ここではその方法を解説しませんが、使用しているEmacsのコードにバグがある場合に同様の状況に遭遇する可能性があるため、その結果がどのようなものになるかについて触れておきます。そのような場合、エラーメッセージは1行だけ表示され、エコーエリアに次のように現れます:
Symbol's function definition is void: this
キーを一つ押すだけで、たとえカーソルを動かすだけであっても、メッセージは消えてしまいます。
「Symbol」という単語の意味は分かっています。これはリストの最初のアトム、つまり「this」という単語を指します。「function」という単語は、コンピュータに何をすべきかを指示する命令を指します。(厳密に言えば、この記号はコンピュータに命令がどこにあるかを伝えるものですが、この点はひとまず無視して構いません。)
エラーメッセージは次のように解釈できます:‘Symbol's function definition is void: this’。この記号(すなわち単語 ‘this’)には、コンピュータが実行すべき指示が含まれていません。