【发布时间】:2014-11-27 09:19:31
【问题描述】:
我正在尝试通过类方法重载给定缓冲区中的更改后函数。 notify-others-of-change 是一个任意函数。
(defmethod set-after-change-functions ((server server-class)
name-of-buffer)
"Adds appropriate after-change-functions to the given name-of-buffer."
(with-current-buffer name-of-buffer
(setq-local after-change-functions
(cons
(lambda (beg end prev-length)
(notify-others-of-change
server beg end prev-length))
after-change-functions))))
当试图在给定的缓冲区上运行它时(传入一个有效的服务器对象,我检查了),Emacs 对我大喊“符号作为变量的值是无效的:服务器”并且 after-change-functions 变为 nil,即使之前有元素。但是,当改为
(defmethod set-after-change-functions ((server server-class)
name-of-buffer)
"Adds appropriate after-change-functions to the given name-of-buffer."
(with-current-buffer name-of-buffer
(setq-local after-change-functions
(cons
#'notify-others-of-change-SIMPLE
after-change-functions))))
其中 notify-others-of-change-SIMPLE 是基本的更改后函数,它只接受上面 lambda 中的三个参数,一切似乎都有效。我更喜欢在这里使用 lambda,但似乎不可能。为什么会出现这个问题,是否可以更改它以允许使用 lambda?
【问题讨论】:
-
您设置了
lexical-binding吗?你的 lambda 函数引用了server,所以它必须是一个闭包才能工作。 -
不要将
setq或setq-local用于挂钩。使用add-hook或remove-hook。 -
你说“我更喜欢在这里使用 lambda”,但是将 lambdas 不必要地放入钩子变量中是不好的做法——它会使更新或删除它们有问题(如果你不这样做会导致错误小心),它使检查钩子变得困难(特别是如果 lambda 是字节编译的),并且无法从钩子跳转到函数定义的代码。由于所有这些原因,您应该更喜欢在挂钩中使用命名函数。