在elisp中,如何将函数放入变量中?

时间:2012-03-30 12:11:59

标签: emacs elisp

我想允许用户在“自定义”emacs后端中选择自己的命令(并且通常能够将可执行的表单名称存储在变量中)但这不起作用:

    (defun dumb-f ()
    (message "I'm a function"))

    (defvar my-function "dumb-f")

    (my-function)
    ==> Debugger entered--Lisp error: (invalid-function "dumb-f")

    (setq my-function 'dumb-f)

    (my-function)
    ==> Debugger entered--Lisp error: (invalid-function "dumb-f")

我尝试了各种各样的形式,但仍然没有运气,而且我很难找到它,我得到了关于函数和变量的结果,但没有关于如何将前者放在后者中??< / p>

3 个答案:

答案 0 :(得分:27)

请注意,在Emacs Lisp中,符号具有值单元格和功能单元格,它们是不同的。评估符号时,会得到。当您评估以该符号开头的列表时,可以调用其函数。这就是为什么你可以拥有一个变量和一个具有相同名称的函数。

大多数类型的作业都会设置价值(例如letsetqdefvardefcustom等等 - 而且正如ryuslash所示,你可以将函数指定为值并通过funcall调用 - 但也有方法使用fset(或fletdefalias直接分配给符号的函数单元格,等)

(fset 'my-function 'dumb-f)
(my-function)

在你的情况下,我会使用ryuslash的答案(除非你需要defcustom而不是defvar,否则你需要使用customize)。

另外,关于“我正在苦苦寻找它”;永远记住Emacs是自我记录,其中包含一个带索引的好手册(实际上,不止一本手册)。因此,即使Google仍然是您的第一个停靠点,如果您找不到所需内容,也不应该是最后一个。在elisp手册的内容页面中,您可以导航到“功能”,然后导航到“调用功能”,您将立即被告知funcall

答案 1 :(得分:16)

要运行存储在变量中的函数,您可以使用funcall

(defun dumb-f ()
  (message "I'm a function"))

(defvar my-function 'dumb-f)

(funcall my-function)
==> "I'm a function"

答案 2 :(得分:1)

@phils的好答案提到了设置符号功能定义的各种方法,但是我还需要获取的方法。

要获取符号值作为函数,可以使用函数symbol-function

例如:

; remember the old value of 'foo as a function
(set 'foo-backup (symbol-function 'foo))
; change it, to experiment or whatever
(defun foo () whatever)
; revert it back to what it was
(fset 'foo foo-backup)

事实上,emacs手册在这里特别有用:

https://www.gnu.org/software/emacs/manual/html_node/elisp/Symbol-Components.html

https://www.gnu.org/software/emacs/manual/html_node/elisp/Function-Cells.html