【发布时间】:2014-10-20 03:56:33
【问题描述】:
我正在尝试将 buffer-local 变量的名称合并到 dolist 循环中,并更改该 buffer-local 变量的值。 setq 和 setq-local 拒绝我尝试过的所有变量名称变体。在dolist循环中,变量名为(car (car (cdr test)))。
相同的变量名将用于多个缓冲区,每个缓冲区具有不同的值。
这个项目与我最近的其他两 (2) 个线程相关,但我相信这是一个有点独特的问题。相关线程如下:How to use `setcdr` with buffer-local variables 和 How to use a cons cell to define and later remove overlays with `dolist`
我尝试了以下所有方法以及其他一些变体,但均未成功:
(setq (car (car (cdr test))) newlist)
(setq var newlist)
(setq (make-symbol (car (car (cdr test)))) newlist)
(setq (intern (car (car (cdr test)))) newlist)
我也尝试过修改列表以使用字符串,例如'("variable-one" ,variable-one)
这是测试代码:
(defvar variable-one '(a t))
(make-variable-buffer-local 'variable-one)
(defvar variable-two '(c t))
(make-variable-buffer-local 'variable-two)
(defvar variable-three '(e t))
(make-variable-buffer-local 'variable-three)
(dolist (test `(
'(variable-one ,variable-one)
'(variable-two ,variable-two)
'(variable-three ,variable-three) ))
(let* (
(var (car (car (cdr test))))
(newlist (copy-list (car (cdr (car (cdr test)))))) )
(setcdr newlist nil)
(message "var: %s | newlist: %s" var newlist)
;; (setq (car (car (cdr test))) newlist)
))
编辑(2014 年 8 月 26 日):以下修订基于此线程中每个人提供的有用建议 - 非常感谢! :) 今天晚些时候我仍然需要对多个缓冲区进行一些缓冲区本地测试,但论坛参与者提出的建议似乎与下面的测试大纲一致。
(defvar variable-one '(a t))
(make-variable-buffer-local 'variable-one)
(defvar variable-two '(c t))
(make-variable-buffer-local 'variable-two)
(defvar variable-three '(e t))
(make-variable-buffer-local 'variable-three)
(dolist (test `(
(variable-one ,variable-one)
(variable-two ,variable-two)
(variable-three ,variable-three) ))
(let* (
(var (car test))
(newlist (copy-list (car (cdr test)))) )
(setcdr newlist nil)
(message "var: %s | newlist: %s" var newlist)
(set (car test) newlist) ))
【问题讨论】:
-
几个快速点。首先,
(car (car (cdr test)))可以更简洁地表示为(caadr test)。其次,你可以使用setf宏来设置像(setf (caadr test) newlist)这样的地方。 -
@Dan -- 感谢您使用
caadr的快捷方式。我需要阅读set(如下 Tom Tromey 所建议)和setf之间的区别——两者似乎都在这个线程中的示例上下文中运行良好。 -
setf是 Common Lisp 的通用设置器,它也可以在 elisp 中使用(实际上,setq在 CL 中的使用相对较少,因为它在很大程度上已被setf取代)。这是the differences betweenset,setq, andsetf上的一个有用线程。 -
"(variable..."前的引号应该是不需要的。反引号就够了。
-
@Drew:实际上
let*绑定值中最里面的cdr和car是为了绕过多余的quote;您必须同时更改两者以保持一致。