我只是花了很长时间才弄清楚我的代码出了什么问题。它在 ert 单元测试中工作得很好,但是当我在更大的上下文中运行它时失败了。这是一个有效的代码示例:
(defun func (my-var)
(with-temp-buffer
(message my-var)))
(func "z")
这会按预期打印 z。现在我正在编写一个主要模式,它有一些缓冲区局部变量。其中之一是 my-var。此代码演示了我的问题:
(make-local-variable 'my-var)
(setq my-var "y")
(defun func (my-var)
(with-temp-buffer
(message my-var)))
(func "z")
输出?没有,只有这个错误信息:
eval-buffer: Symbol's value as variable is void: my-var
在这个例子中很容易看出局部缓冲区变量以某种方式干扰了动态绑定(bind)的 my-var。当我有多个屏幕的代码时,这并不是那么容易:-)
所以我的问题是这里到底发生了什么?很明显,临时缓冲区以某种方式从“父”缓冲区继承了一个变量,但为什么它有一个空值?我会理解它是否会以某种方式获得值“y”,但这种行为对我来说就像一个错误。
附言。我正在运行最新的 Aquamacs
最佳答案
几件事。
首先,您的代码无法按原样运行。您应该在新的 Emacs 调用中尝试这样做。完成后,您会看到需要向 make-local-variable
传递一个符号,如下所示:
(make-local-variable 'my-var)
注意```。
其次,您定义了一个缓冲区局部变量,使其与 func
的参数同名,因此任何答案都需要区分两者。
所以,这是我对您的示例的清理版本:
(make-local-variable 'my-var)
(setq my-var "y")
(defun func (my-param)
(with-temp-buffer
(message my-param)))
(func "z")
这很好用。
这让我相信您看到的错误是由于调用 make-local-variable
而在 my-var
前面没有引号引起的。
下面提供了原始答案,但它没有解决问题:
查看 make-local-variable
的文档.文档字符串是:
make-local-variable is an interactive built-in function in `C source code'.
(make-local-variable VARIABLE)
Make VARIABLE have a separate value in the current buffer. Other buffers will continue to share a common default value. (The buffer-local value of VARIABLE starts out as the same value VARIABLE previously had. If VARIABLE was void, it remains void.) Return VARIABLE.
对你来说关键的部分是最后一句话。 如果变量为 void,则它保持为 void。
这意味着如果它还没有在全局定义,它仍然没有在全局定义。换句话说,它仅在已明确设置的缓冲区中具有绑定(bind)。
如果您希望它具有全局值,请像这样使用 setq-default
:
(setq-default my-var "some-default-value")
关于dynamic - 当 "parent"缓冲区具有我绑定(bind)的同名局部变量时,为什么 with-temp-buffer 中的代码会提示 void 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9008359/