flet工作,但有过时的消息; cl-flet不起作用

时间:2013-06-25 17:37:09

标签: emacs

我正在尝试暂时关闭其他地方定义的函数中的yes-or-no-p,然后将其恢复到原来的状态。使用flet有效,但会创建一个*compile-log*缓冲区,告诉我它已过时并改为使用cl-flet。然而,cl-flet似乎不适用于defadvice的这种尝试 - 即没有任何反应,是或否-p仍然有效。有关如何避免错误消息以及使其工作的任何想法吗?

(defun function-without-confirmation ()

(defadvice elmo-dop-queue-flush (around stfu activate)
      (flet ((yes-or-no-p (&rest args) t)
             (y-or-n-p (&rest args) t))
        ad-do-it))

. . . .


(ad-unadvise 'elmo-dop-queue-flush)

)

我不能肯定答案,因为这是wvxvw解决的,所以我会在原始问题下面放置相关的修补程序。新宏被称为lawlist-flet flet的{​​{1}},并且已过时的行被注释掉了:

(defmacro lawlist-flet (bindings &rest body)
  "Make temporary overriding function definitions.
This is an analogue of a dynamically scoped `let' that operates on the function
cell of FUNCs rather than their value cell.
If you want the Common-Lisp style of `flet', you should use `cl-flet'.
The FORMs are evaluated with the specified function definitions in place,
then the definitions are undone (the FUNCs go back to their previous
definitions, or lack thereof).

\(fn ((FUNC ARGLIST BODY...) ...) FORM...)"
  (declare (indent 1) (debug cl-flet)
;;           (obsolete "use either `cl-flet' or `cl-letf'."  "24.3")
                )
  `(letf ,(mapcar
           (lambda (x)
             (if (or (and (fboundp (car x))
                          (eq (car-safe (symbol-function (car x))) 'macro))
                     (cdr (assq (car x) macroexpand-all-environment)))
                 (error "Use `labels', not `flet', to rebind macro names"))
             (let ((func `(cl-function
                           (lambda ,(cadr x)
                             (cl-block ,(car x) ,@(cddr x))))))
               (when (cl--compiling-file)
                 ;; Bug#411.  It would be nice to fix this.
                 (and (get (car x) 'byte-compile)
                      (error "Byte-compiling a redefinition of `%s' \
will not work - use `labels' instead" (symbol-name (car x))))
                 ;; FIXME This affects the rest of the file, when it
                 ;; should be restricted to the flet body.
                 (and (boundp 'byte-compile-function-environment)
                      (push (cons (car x) (eval func))
                            byte-compile-function-environment)))
               (list `(symbol-function ',(car x)) func)))
           bindings)
     ,@body))

并且,这是修改后的函数,它消除了与flet过时相关的错误消息。

(defun function-without-confirmation ()

(defadvice elmo-dop-queue-flush (around stfu activate)
      (lawlist-flet ((yes-or-no-p (&rest args) t)
             (y-or-n-p (&rest args) t))
        ad-do-it))

. . . .


(ad-unadvise 'elmo-dop-queue-flush)

1 个答案:

答案 0 :(得分:3)

以下是我建议你这样做的方法:

(defvar stfu-inhibit-yonp nil)
(defadvice yes-or-no-p (around stfu activate)
  (if stfu-inhibit-yonp (setq ad-return t) ad-do-it))
(defadvice y-or-n-p (around stfu activate)
  (if stfu-inhibit-yonp (setq ad-return t) ad-do-it))

(defadvice elmo-dop-queue-flush (around stfu activate)
  (let ((stfu-inhibit-yonp t))
    ad-do-it))

与CL flet相反,这将清楚地表明(例如在C-h f yes-or-no-p中)某些事情正在发生在是或否 - p。