为什么 with-temp-buffer 中的代码在缓冲区具有我绑定的同名的局部变量时"parent"抱怨 void 变量?



我只是花了很长时间才弄清楚我的代码出了什么问题。它在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

在这个例子中,很容易看出缓冲区局部变量以某种方式干扰了动态绑定的my-var。当我有多个屏幕的代码时,这并不是那么容易:-)

所以我的问题是这里到底发生了什么?很明显,临时缓冲区以某种方式从"父"缓冲区继承了一个变量,但为什么它有一个void值呢?如果它以某种方式得到值"y",我会理解,但这种行为对我来说就像一个bug

PS。我正在运行最新的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局部变量是`C源中的一个交互式内置函数代码'。

(使局部变量可变)

使VARIABLE在当前缓冲区中有一个单独的值。另外缓冲区将继续共享一个共同的默认值。(VARIABLE的缓冲区本地值开始时为相同的值VARIABLE以前有。如果VARIABLE为空,它将保持为空。)回来变量。

对你来说,关键部分是最后一句话。If the variable was void, it remains void.

这意味着,如果它还没有全局定义,那么它仍然没有全局定义。换句话说,它在显式设置的缓冲区中只有一个绑定。

如果您希望它具有全局值,请使用setq-default,如下所示:

(setq-default my-var "some-default-value")

最新更新