I am experiencing behavior using setcdr
that would seem to suggest that it is not confined to buffer-local variables containing the same name in different buffers. I have tried using with-current-buffer
, but that does not correct the issue.
For example, buffer-A
and buffer-B
both contain a local-variable named variable-one
, which is a cons
cell -- e.g., (overlay-string t)
, and setcdr
is being used to set the cdr
value to either t
or nil
.
Is there a way to ensure that setcdr
remains confined to modifying only the buffer-local value?
No, there is no buffer-local value for the cdr of the list.
If two variables point at the same list, and you modify the list, then you will see the effect in both the variables.
That has nothing to do with buffer-local variables, and everything to do with what it means to assign a list to a variable.
If you want the two variables to point to different lists, then you need to copy the entire list.
You can use (copy-sequence LIST)
to copy a list. Or (append LIST nil)
is also common (as append copies all except the final argument).
n.b. Those functions create a new list structure, but the values in the list are still the original objects. Typically that's all that's required, but if you do need the list contents to be entirely independent of one another, then use copy-tree
instead.
I don't think you can, as with setcdr
you are modifying the value bound to the variable you declared buffer-local. If you didn't assign a new value to the buffer-local variable, that value is its default value. Note that what is buffer local is the binding of the variable name to its value.
The only way (that I know) would be to assign a copy to your buffer-local variable and then use setcdr
.
This needs to be done in every buffer.
An alternative is to not use setcdr
at all, and use setq
instead:
(setcdr foo bar) ===> (setq foo (cons (car foo) bar))