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

Emacs 在elisp中,如何将函数放入变量中?,emacs,elisp,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-fun

我希望允许用户在“定制”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")

我尝试了各种形式,但仍然没有成功,我很难找到它,我得到了数千页关于函数和变量的结果,但没有关于如何将前者放入后者的结果。

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

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

(defvar my-function 'dumb-f)

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

请注意,在Emacs Lisp中,符号有一个值单元格和一个函数单元格,它们是不同的。对符号求值时,将获得其值。当计算以该符号开头的列表时,调用其函数。这就是为什么可以使用相同名称的变量和函数

大多数类型的赋值都会设置值(例如,
let
setq
defvar
defcustom
,等等)——正如ryuslash所示,您可以将函数赋值为值,并通过
funcall
调用它——但也有一些方法可以直接使用
fset
将其赋值给符号的函数单元(或
flet
defalias
等)

(fset'my function'dumb-f)
(我的职能)
在您的情况下,我将使用ryuslash的答案(如果您希望通过
自定义
,则需要使用
defcustom
而不是
defvar


另外,关于“我很难在谷歌上找到它”;请记住Emacs是自我文档化的,而且其中包含一个很好的手册,其中包括索引(事实上,不止一个手册)因此,即使谷歌仍然是你的第一个呼叫端口,如果你找不到你要找的东西,它也不应该是你的最后一个呼叫端口。从elisp手册的内容页,你可以导航到“函数”,然后是“调用函数”您将立即了解
funcall

@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手册在这里非常有用,特别是:


我的示例选择得很糟糕,抱歉:我想使用customize to,比如让用户选择其邮件程序,如下所示:
(defcustome My mail program“gnus”mail client命令。示例:wl:type'string:group'mail bugger)
我无法执行(我的邮件程序)..?因此,您应该使用
:type'function
而不是
'string
,默认值为
'gnus
而不是
“gnus”
,然后使用
(funcall my mail program)
。确保您理解字符串和符号之间的区别。这是一个很好的技巧,但是它将符号
dumb-f
存储在symbol
my function
的函数槽中。这意味着如果覆盖
dumb-f
的定义,则
my function
现在将指向新的定义。为了避免为此,请使用Alekseyev的解决方案:
(fset'my function(symbol function'dumb-f))
。请注意,这并不存储函数,而是存储符号
dumb-f
,当传递到
funcall
时,将对其函数值进行求值。如果覆盖函数,则此区别很重要:现在将调用新函数。因此,如果要“备份”要在以后调用原始函数,需要使用@arseniy alekseyev的答案。