elisp 中捕获错误案例的最佳方法是什么



我正在尝试增强etags select函数,这样,如果find标记在某个点失败,它将返回到正常的find标记。我尝试过的代码是:

(defun my-etags-find-tag ()
  "Find at point or fall back"
  (interactive)
  (unless (etags-select-find-tag-at-point)
    (etags-select-find-tag)))
(global-set-key (kbd "C-f") 'my-etags-find-tag)

但是,当不在有效标记处时,此操作将失败。相反,我得到了一个错误,由etags select find标记抛出:

etags-select-find-tag-at-point: Wrong type argument: char-or-string-p, nil

在这种情况下,我只需要重复etags在点选择查找标签所做的测试:

(defun my-etags-find-tag ()
  "Find at point or fall back"
  (interactive)
  (if (find-tag-default)
      (etags-select-find-tag-at-point)
    (etags-select-find-tag)))

但这看起来确实有点多余。是否可以在elisp中捕获异常并进行交替处理?

尝试ignore-errors;例如

(unless (ignore-errors (etags-select-find-tag-at-point))
  (etags-select-find-tag))

通常,(ignore-errors body)返回body返回的任何内容;当出现错误时,返回nil

还要查看condition-case,了解更一般的条件处理。

如果您安装了Elisp信息手册,您可以从C-hSCCD_ 6。

编辑:

我没有考虑到该功能成功后可能返回零的可能性;所以我们可能需要

(unless (ignore-errors (or (etags-select-find-tag-at-point) t))
  (etags-select-find-tag))

在不修改etags-select.el的原始源代码的情况下,我认为它是更合理的选项,即使它对find-tag-default调用了两次。您可以通过以下方式来欺骗调用中的动态环境,以避免调用的重复:

(defun my-etags-find-tag ()
  "Find at point or fall back"
  (interactive)
  (let ((ftd (find-tag-default)))
    (flet ((find-tag-default () ftd))
      (if (find-tag-default)
          (etags-select-find-tag-at-point)
        (etags-select-find-tag)))))

编辑:好的,根据您的要求,对代码进行解释。首先,请注意,此代码实现了两个问题:

  1. 它不会失败
  2. 它比你显示的代码(你说它是多余的)更有效率

为什么它更高效?冗余代码的问题在于,您调用find-tag-default来查看它是否为nil,如果是,则调用etags-select-find-tag-at-point。此函数再次调用find-tag-default以获得默认值。我的代码所做的是缓存find-tag-default的值,方法是将函数重新定义为您计算的值。flet这样做,所以当etags-select-find-tag-at-point调用find-tag-default时,计算的值被返回,而不需要任何进一步的处理。

相关内容

最新更新