【问题标题】:Emacs: how hooks work?Emacs:钩子是如何工作的?
【发布时间】:2014-09-18 19:40:42
【问题描述】:

我已经阅读了不同的教程和手册,但仍然无法将东西放在一起。

据我了解,当我需要在一个事件中添加一个新函数而一个旧函数仍然保存时,我通过调用 add-hook 添加一个钩子。从add-hook上的手动输入:

在钩子列表的开头添加(如果需要)FUNCTION 除非可选参数 APPEND 不为零

所以钩子只是一个函数的列表。但是这个列表看起来怎么样?作品?从我的小研究中,我发现除了 carcdr 之外的每个 cons 单元格 还有一个不可见的未提及的函数指针插槽(可能是索引,没关系)。那么如何手动创建函数列表并执行它呢?可能使用add-to-list 函数,但我尝试的所有操作都会触发错误。手册中还有mentioned

您可以像任何其他 Lisp 变量一样使用 setq 设置挂钩变量,

这里出了点问题,因为指向函数的指针没有被 setq 复制。即:

(defun myfunc1 () (message "hello"))
(setq onemorefunc 'myfunc1)

在我执行(onemorefunc) 后,调试器触发,setq 只是忽略存储指针的未命名元素的值。

【问题讨论】:

    标签: function emacs elisp hook


    【解决方案1】:

    要调用变量中的函数,您必须使用funcallapply

    (funcall onemorefunc)
    
    (apply onemorefunc '())
    

    当 Emacs 处理一个钩子变量时,它会遍历列表:

    (do ((hooks blah-hook (cdr hooks)))
        ((null hooks))
      (funcall (car hooks)))
    

    【讨论】:

    • 另外,有关更多信息,请查看有关running hooks的手册
    【解决方案2】:

    在您的示例中,您的setq 只是使onemorefunc 成为myfunc1 的另一个名称。钩子必须是一个列表,您需要使用add-hook 将钩子函数添加到该列表中,这是push 的美化版本,而不是使用setq 将列表完全替换为您的函数。 setq 的提及误导了你,尽管熟悉钩子的人很清楚它告诉你一些正确的事情else。它说你可以使用setq 设置一个钩子变量——而不是钩子本身——你可以,但不清楚的是你必须设置那个钩子变量to 是另一个列表(零个或多个函数)而不是函数。因此,假设 my-mode-start-hook 开始为空:

    (add-hook 'my-mode-start-hook #'my-func)
    

    相当于:

    (setq my-mode-start-hook (list #'my-func))
    

    在实践中,你应该总是做前者,永远不要做后者,除非你真的确定你知道自己在做什么。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-03
      • 1970-01-01
      • 1970-01-01
      • 2023-01-09
      • 2020-11-03
      • 2021-06-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多