问题描述
我正在尝试暂时关闭在别处定义的函数中的 yes-or-no-p
,然后将事情恢复到原来的状态.使用 flet
可以工作,但会创建一个 *compile-log*
缓冲区,告诉我它已过时并改用 cl-flet.但是,cl-flet 似乎不适用于 defadvice
的这种尝试——即,没有任何反应,yes-or-no-p 保持活动状态.关于如何避免错误消息并使这项工作也起作用的任何想法?
I'm trying to temporarily turn off the yes-or-no-p
within a function that is defined elsewhere and then restore things to the way they were. Using flet
works, but creates a *compile-log*
buffer telling me that it is obsolete and to use cl-flet instead. However, cl-flet doesn't seem to work with this attempt at defadvice
-- i.e., nothing happens and the yes-or-no-p remains active. Any ideas on how to avoid the error message and make this work also?
(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
instad 的 flet
,过时的行已被注释掉:
I cannot take credit for the answer, because that was solved by wvxvw
, so I'll put the relevant fix underneath the original question. The new macro is called lawlist-flet
instad of flet
, and the obsolete line has been commented out:
(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
已过时相关的错误消息.
And, here is the modified function that eliminates the error message relating to flet
being obsolete.
(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)
推荐答案
我建议您这样做:
(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
相反,这将清楚地表明(例如在 Ch f yes-or-no-p
中)是或否发生了某些事情-
Contrary to CL's flet
this will make it clear (e.g. in C-h f yes-or-no-p
) that something's going on with yes-or-no-p.
这篇关于flet 可以工作,但带有过时的信息;cl-flet 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!