关联如何设置值到函数执行的结果



在高层:我试图创建一个关联列表,其中值是函数执行的结果。我得到的是一个表示该函数的表达式,它需要被包装成&;eval&;让它工作。我试图理解为什么,以及是什么使这种行为与常规列表不同。

详细说明:

我正在为org议程组合一个配置,它具有所有环境的通用功能,但然后我想使特定环境能够添加一些额外的东西。所以,我知道在所有的机器上,组织-议程-文件需要包括这两个目录:"~/Documents/组织"one_answers"~/下载/Org"但是我想让一个特定的机器除了这两个之外注册更多的dirs,这些dirs只对该机器可见。

所以我建立了一个关联列表,其中机器名是键,值是需要在该节点上处理的目录列表,以及所有共享的目录。

代码如下:

;; default-agenda-files are shared by all the environments
(setq default-agenda-files
'("~/Documents/Org" "~/Downloads/Org"))
;; in addition to default, I want to register project-abc
;; dirs for nodeABC and project-xyz dirs for nodeXYZ
(setq per-node-agenda-file-mappings
'(("nodeABC" . (append default-agenda-files
'("~/Projects/project-abc/doc/"
"~/Projects/project-abc/notes")))
'("nodeXYZ" . (append default-agenda-files
'("~/Projects/project-xyz/doc"
"~/Projects/project-xyz/notes")))))

代码进一步根据机器名设置org-agenda-files。

问题在这里。如果我做

(alist-get "nodeABC" per-node-agenda-file-mappings nil nil 'string-equal)

(append default-agenda-files '("~/Projects/project-abc/doc/" "~/Projects/project-abc/notes"))

而不是

("~/Documents/Org" "~/Downloads/Org" "~/Projects/project-abc/doc/" "~/Projects/project-abc/notes")

我可以通过

来解它
(eval (alist-get "nodeABC" per-node-agenda-file-mappings nil nil 'string-equal))

那么一切都正常了。

但是我试图理解那里发生了什么,为什么同样的事情不会发生在常规列表中(对于常规列表,评估确实发生在赋值时)。在这种情况下,有没有办法在分配作业的时候进行评估呢?我仔细检查了一下,如果我使用哈希表而不是关联列表,也会发生同样的事情。

使用其他列表中的列表并没有什么不同。你要做的是评估一些东西,而不是评估其他东西。只要这样做:只引用你不想求值的东西。

你不需要显式地调用eval——Lisp已经隐式地调用了它。您所需要做的就是而不是计算您想要视为数据的东西。在这里,这意味着字符串(无论如何,它们都是常量,所以对它们求值没有区别)和任何你想要的列表——好吧,列表——例如,'("~/Projects/project-abc/doc/" "~/Projects/project-abc/notes").


您希望使用反引号而不是引号,并在(append...)sexp:

之前使用逗号
(setq per-node-agenda-file-mappings
`(("nodeABC" . ,(append default-agenda-files
'("~/Projects/project-abc/doc/"
"~/Projects/project-abc/notes")))
("nodeXYZ" . ,(append default-agenda-files
'("~/Projects/project-xyz/doc"
"~/Projects/project-xyz/notes")))))

或:

(setq per-node-agenda-file-mappings
`(("nodeABC" ,@(append default-agenda-files
'("~/Projects/project-abc/doc/"
"~/Projects/project-abc/notes")))
("nodeXYZ" ,@(append default-agenda-files
'("~/Projects/project-xyz/doc"
"~/Projects/project-xyz/notes")))))

或:

(setq per-node-agenda-file-mappings
(list (cons "nodeABC" (append default-agenda-files
'("~/Projects/project-abc/doc/"
"~/Projects/project-abc/notes")))
(cons "nodeXYZ" (append default-agenda-files
'("~/Projects/project-xyz/doc"
"~/Projects/project-xyz/notes")))))

或者就是这个,因为您唯一需要计算的是变量default-agenda-files:

(setq per-node-agenda-file-mappings
`(("nodeABC" ,@default-agenda-files
"~/Projects/project-abc/doc/" "~/Projects/project-abc/notes")
("nodeXYZ" ,@default-agenda-files
"~/Projects/project-xyz/doc" "~/Projects/project-xyz/notes")))

参见Elisp手册,node Backquote。

最新更新