ScratchBuffer里面
(defun my-function (arg)
"test my-function"
(interactive "stest:")
(message arg))
(advice-add 'my-function
:before
(lambda () (message "Before calling my-function")))
(advice-add 'my-function
:after
(lambda (&rest _) (message "After calling my-function")))
不懂就问,上面执行M-x my-function 然后随便输入点什么,执行的时候报错
apply: Wrong number of arguments: (lambda nil (message “Before calling my-function”)), 1
是为什么?
在看了 关于 advice 的参数数目 - #14,来自 et2010 后,
(advice-add 'my-function
:before
(lambda (&rest _) (message "Before calling my-function")))
(advice-add 'my-function
:after
(lambda (&rest _) (message "After calling my-function")))
给加了参数,但是好像还是没能解决问题,还是报错
然后我猜想是不是 我再去 在Scratch 中 C-j,它就又加了一个 advice。那相当于我有好几个before了(执行了好几次)。那么这种情况下,想问
- 怎么清除所有的advice,
(advice-mapc #'advice-remove 'my-function)
chatgpt给了一个这个,但是好像不行
- 我在Scratch中 C-j 运行生效的函数,怎么让他失效,不能重启吧。。。
advice-add 最好不要用lambda. 用defun 这样不会重复 add,而且也方便remove.
LdBeth
4
我不太想解釋怎么做的,看 nadvice.el
代码得出的
(remove-function
(symbol-function 'my-function)
(lambda () (message "Before calling my-function")))
(remove-function
(symbol-function 'my-function)
(lambda (&rest _) (message "After calling my-function")))
新版的 advice 是用重新抽象出来的 oclosure 实现的,旧版也有同样界面的 API 不过是通过注入 byte-code 实现的
(oclosure-define (advice
(:predicate advice--p)
(:copier advice--cons (cdr))
(:copier advice--copy (car cdr how props)))
car cdr how props)
如果是两个 advice 都在的情況
(advice--car (symbol-function 'my-function))
;; (lambda (&rest _) (message "After calling my-function"))
(advice--car (advice--cdr (symbol-function 'my-function)))
;; (lambda nil (message "Before calling my-function"))
(advice--cdr (advice--cdr (symbol-function 'my-function)))
;; (lambda (arg) "test my-function" (interactive "stest:") (message arg))
如果没法通过 equal
比较删除,手动 fset
回去也不是不行。
或者写个函数
(defun advice-last (f)
(if (advice--p f)
(advice-last (advice--cdr f))
f))
(fset 'my-function (advice-last (symbol-function 'my-function)))
这种自己写了个函数的情况,估计还是 fmakunbound
再 eval 定义会快些