【问题标题】:Incorporate variable name into `dolist` cycle and change its value将变量名合并到 `dolist` 循环中并更改其值
【发布时间】:2014-10-20 03:56:33
【问题描述】:

我正在尝试将 buffer-local 变量的名称合并到 dolist 循环中,并更改该 buffer-local 变量的值。 setqsetq-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 between set, setq, and setf 上的一个有用线程。
  • "(variable..."前的引号应该是不需要的。反引号就够了。
  • @Drew:实际上let*绑定值中最里面的cdrcar是为了绕过多余的quote;您必须同时更改两者以保持一致。

标签: emacs elisp


【解决方案1】:

我不知道你所说的“dolist cycle”是什么意思。

问题的根源在于setq 是一种特殊形式。第一个参数不需要被引用——这就是“q”的意思。

您想改用set

【讨论】:

  • 谢谢 - 看起来它成功了。今天早上我将使用多个缓冲区进行更多测试,并在今天晚些时候报告。非常感谢!
  • 一般来说,如果您需要set(和/或symbol-valueeval,以及他们的一些亲戚),您可能做错了什么。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-01
  • 2013-09-27
  • 2022-07-06
  • 2019-10-08
  • 1970-01-01
相关资源
最近更新 更多