部分原因是,如果您不小心出错了,也不用担心,我们现在将向 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) eval((this is an unquoted list) nil) elisp--eval-last-sexp(nil) 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解释器接下来评估的内容。最新的操作在顶部。这个缓冲区被称为 *Backtrace* ,因为它允许我们回溯Emacs的执行步骤。
在 *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代码遇到类似情况时,也可能看到类似的效果。在这种情况下,您只会看到一行错误信息;它会出现在回显区,看起来像这样:
Symbol's function definition is void: this
当你输入任何键,哪怕只是移动一下光标,这个消息就会消失。
我们知道‘Symbol’这个词的含义。它指代的是列表中的第一个原子,也就是词‘this’。‘function’一词表示用于告知计算机要执行什么操作的指令。(技术上来说,这个符号会告知计算机在何处可以找到这些指令,但这个复杂问题我们暂时可以忽略。)
所以错误信息可以这样理解:‘Symbol's function definition is void: this’。这个符号(Symbol)(也就是词‘this’)缺少可供计算机执行的指令。