0

I am trying to incorporate the name of a buffer-local variable into the dolist cycle, and change the value of that buffer-local variable. setq and setq-local reject all of the variable name variations that I have tried. In the dolist cycle, the variable name is (car (car (cdr test))).

The same variable name will be used in more than one buffer, with each buffer having a different value.

This project is related two (2) other recent threads of mine, but I believe this is a somewhat unique issue. The related threads are as follows:  How to use `setcdr` with buffer-local variables and How to use a cons cell to define and later remove overlays with `dolist`

I have tried all of the following, and a few other variations, without success:

(setq (car (car (cdr test))) newlist)

(setq var newlist)

(setq (make-symbol (car (car (cdr test)))) newlist)

(setq (intern (car (car (cdr test)))) newlist)

I have also tried modifying the list to use a string, e.g., '("variable-one" ,variable-one)


Here is the test code:

(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)
  ))

EDIT (August 26, 2014):  The following revision is based upon the helpful suggestions provided by everyone in this thread -- greatly appreciated! :) I still need to conduct some buffer-local tests with multiple buffers later on today, but the suggestions made by the forum participants seem to work with the test outline below.

(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) ))
Community
  • 1
  • 1
lawlist
  • 13,099
  • 3
  • 49
  • 158
  • 1
    Couple of quick points. First, `(car (car (cdr test)))` can be expressed more compactly as `(caadr test)`. Second, you can use the `setf` macro to set places like `(setf (caadr test) newlist)`. – Dan Aug 26 '14 at 18:36
  • @Dan -- thank you for the shortcut using `caadr`. I'll need to read up on the difference between `set` (as suggested by Tom Tromey below) and `setf` -- both seem to work well in the context of the example in this thread. – lawlist Aug 26 '14 at 18:49
  • 1
    `setf` is the general setter for Common Lisp, and it works in elisp as well (actually, use of `setq` is relatively rare in CL, as it has largely been superceded by `setf`). Here's a useful thread on [the differences between `set`, `setq`, and `setf`](http://stackoverflow.com/questions/869529/difference-between-set-setq-and-setf-in-common-lisp). – Dan Aug 26 '14 at 18:53
  • 1
    Should be no need for the quote marks before "(variable...". The backquote suffices. – Drew Aug 26 '14 at 19:44
  • @Drew -- without the single quote before `(variable...`, I get `. . . (wrong-type-argument listp t)` – lawlist Aug 26 '14 at 20:10
  • That's because the arg to `copy-list` is `(cadr (cadr test))` and `test` is `(variable-one (a t))`. It has nothing to do with what I mentioned. Your variables have the wrong values, or you are using the wrong `car` and `cdr` combinations, depending on what you want. You can test this kind of thing yourself. Just add binding `(IGNORE (debug))` after the first binding, for example. – Drew Aug 26 '14 at 21:17
  • 1
    @Drew: actually the innermost `cdr` and `car` in the `let*` binding values are for getting past the redundant `quote`; you have to change both at once to stay consistent. – npostavs Aug 26 '14 at 21:36
  • @npostavs: Sure, no doubt. My point was not that simply removing the quote marks would make his code do something useful. The point is that there is no need to quote anything here. – Drew Aug 27 '14 at 02:00

1 Answers1

2

I don't know what you mean by the "dolist cycle".

The root of your problem is that setq is a special form. The first argument doesn't need to be quoted -- that is what the "q" means.

You want to use set instead.

Tom Tromey
  • 21,507
  • 2
  • 45
  • 63
  • Thank you -- that looks like it did the trick. I'll do some more testing this morning with multiple buffers and report back later today. Greatly appreciated! – lawlist Aug 26 '14 at 18:33
  • 2
    As a general rule, if you need `set` (and/or `symbol-value`, `eval`, and a few of their relatives) you're probably doing something wrong. – Stefan Aug 27 '14 at 02:52