【问题标题】:What's the best way in elisp to trap an error caseelisp中捕获错误情况的最佳方法是什么
【发布时间】:2012-07-24 20:08:50
【问题描述】:

我正在尝试增强 etags-select 功能,以便在 find-tag 点失败时回退到正常的 find-tag。我试过的代码是:

(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)

但是,当 point 不在有效标签上时,这会失败。相反,我收到 etags-select-find-tag-at-point 引发的错误:

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

在这种情况下,我只需要重复 etags-select-find-tag-at-point 所做的测试:

(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 中捕获异常并进行交替处理?

【问题讨论】:

    标签: emacs elisp


    【解决方案1】:

    试试ignore-errors;例如,

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

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

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

    如果您安装了 Elisp 信息手册,您可以从 C-hSignore-errors.

    编辑:

    我没有考虑到函数成功返回 nil 的可能性;所以我们可能需要

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

    【讨论】:

    • 但是忽略错误也不能避免调用find-tag-default 两次。
    • 它也失败了。如果没有发生错误,etags-select-find-tag-at-point 仍然返回 'nil 并因此失败。
    • 我接受这个答案,因为它回答了关于捕获错误案例的问题。但是,Deigo 的回答仍然非常有用且具有启发性。
    【解决方案2】:

    在不修改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 时,计算的值会被返回而不需要任何进一步的处理。

    【讨论】:

    • 恐怕你得再解释一下。我不确定我是否看到了这种方法的好处。
    • 好的,我会详细说明我的答案。
    猜你喜欢
    • 1970-01-01
    • 2013-08-29
    • 2019-08-20
    • 1970-01-01
    • 2012-10-10
    • 2010-09-10
    • 1970-01-01
    相关资源
    最近更新 更多