首页 > 解决方案 > 运行计时器时出错:Emacs init.el 中的(无效变量消息)

问题描述

为什么我会Error running timer: (void-variable message) 在我的 `init.el - Emacs 中进入下面的函数?

(defun cypher/cowsayx-sclock (in-minutes message)
  (interactive "nSet the time from now - min.: \nsWhat: ")
  (run-at-time (* in-minutes 60)
               nil
               (lambda ()
                 (message "%S" message)
                 (shell-command (format "xcowsay %s" (shell-quote-argument
                                                      message))))))

标签: variablescompiler-errorsemacselisplexical-closures

解决方案


您需要打开lexical-binding,因为messagelambda 中的该事件不会被视为自由变量。它是 function 的局部词法变量cypher/cowsayx-sclock,但在 lambda 中它是免费的。

否则,您需要替换lambda 表达式中的变量message,并将其用作列表。这是一个反引号表达式,它为您提供了message替换值的列表。

`(lambda ()
   (message "%S" ',message)
   (shell-command (format "xcowsay %s" (shell-quote-argument ',message)))

但这比 using 的性能要差lexical-binding,后者会为 lambda 生成一个闭包,封装 的值message

请参阅 Elisp 手册,节点Using Lexical Binding

例如,您可以将其放在注释行的末尾作为文件的第一行:

  -*- lexical-binding:t -*-

例如,如果您的代码在文件中,foo.el那么这可能是它的第一行:

;;; foo.el --- Code that does foo things.   -*- lexical-binding:t -*-

推荐阅读