8.2.1 condition-case

正如我们之前所见(see Generate an Error Message),当 Emacs Lisp 解释器无法求值某一表达式时, 会提供相应提示;专业术语称之为“触发错误(signaling an error)”。 通常计算机会中断程序并显示提示信息。

然而,部分程序会执行复杂操作,不应因错误直接停止运行。 在 kill-region 函数中,最常见的错误 是尝试删除只读且无法移除的文本。 因此 kill-region 函数包含处理该情况的代码。 这段构成 kill-region 主体的代码, 被包裹在 condition-case 特殊形式内部。

condition-case 的模板形式如下:

(condition-case
  var
  bodyform
  error-handler...)

第二个参数 bodyform 较为直观。 condition-case 特殊形式会让 Lisp 解释器 对 bodyform 中的代码进行求值。 若未发生错误,该特殊形式会返回代码的执行结果, 并产生相应的副作用(如有)。

简而言之,condition-case 表达式中的 bodyform 部分定义了一切正常时的执行逻辑。

若发生错误,触发错误的函数除其他操作外, 还会定义一个或多个错误条件名称。

错误处理函数是 condition-case 的第三个参数。 每个错误处理函数包含两部分:condition-namebody。若错误处理函数的 condition-name 与错误触发的条件名称匹配,则执行该处理函数的 body 部分。

不难理解,错误处理函数的 condition-name 可以是单个条件名称,也可以是条件名称列表。

此外,完整的 condition-case 表达式 可以包含多个错误处理函数。发生错误时, 会执行第一个匹配的处理函数。

最后,condition-case 表达式的第一个参数 var,有时会绑定为存储错误信息的变量。 但若该参数为 nil(如 kill-region 中), 则会直接丢弃错误信息。

简单来说,kill-region 函数中的 condition-case 逻辑如下:

If no errors, run only this code
    but, if errors, run this other code.