我正在尝试Emacs词汇范围(Emacs 24的新功能)和add-to-list
之间的相互作用,并发现相互作用令人困惑,我不知道如何理解它。这是一个最小的示例,但我使用set
而不是add-to-list
。 (set
与add-to-list
类似,因为它通常采用带引号的变量名称)
(eval
'(progn
(setq a "global")
(let ((a "apple"))
(defun my-print-a ()
(print a)
(set 'a "by set")
(print a))
(setq a "mature apple"))
(let ((a "banana"))
(my-print-a))
(print a))
t) ;; t for lexical scoping
以上代码依次打印“成熟苹果”,“成熟苹果”,“按套”。第一个打印结果,“成熟的苹果”,与词汇范围(支持词汇封闭)一样预期,这里没什么好看的。但第二次和第三次印刷的结果令我感到惊讶。好像(set 'a "by set")
只是识别并影响名称a
的全局绑定。
这是预期的行为吗?或者这是一个错误?如果打算,如何理解这种行为?
我是否正确地认为,只要词法范围界定,set
会影响全局约束?
使用(eval '(progn ...) nil)
,事情按预期的方式运行动态范围,(set 'a ...)
的行为与(setq a ...)
的行为相同。只有当一个人使用词汇作用域和一个引用的变量时,才会出现这个问题。
更新
根据手册,它似乎是一种预期的行为。在Void Variables上,手册说
在词法绑定规则下,值单元格仅保存变量的全局值,即任何词法绑定构造之外的值。当一个变量是词法绑定时,本地值由词汇环境决定;如果变量的符号的值单元格未分配,则该变量可能具有本地值。
symbol-value,boundp和set之类的函数只检索或修改变量的动态绑定(即其符号的值单元格的内容)。
symbol-value,boundp,set是通常使用带引号的变量名称((symbol-value 'var) (boundp 'var) (set 'var 123)
)调用的函数。这些函数仅获取或设置符号的值单元格,并且在词法绑定规则下,值单元格仅保存全局值。因此,在词法绑定下,使用引用变量只获取或设置全局值(除非变量是特殊变量)。虽然结果仍然是奇怪的,但结果既不是词汇(苹果)也不是动态(香蕉)。
答案 0 :(得分:1)
代码不是以Emacs期望编写启用词汇范围的程序的方式编写的。
http://www.gnu.org/software/emacs/manual/html_node/elisp/Definitions.html
defvar
和defconst
是将符号定义为全局变量的特殊形式 - 可以在Lisp程序中的任何位置访问的变量。(...)
原则上,您可以将变量值分配给
setq
的任何符号,无论它是否首先被定义为变量。但是,您应该为要使用的每个全局变量编写变量定义;否则,如果使用词法作用域进行评估,则您的Lisp程序可能无法正常运行。
http://www.gnu.org/software/emacs/manual/html_node/elisp/Lexical-Binding.html
请注意,
symbol-value
,boundp
和set
等函数仅检索或修改变量的动态绑定(即其符号的值单元格的内容)。此外,defun
或defmacro
正文中的代码无法引用周围的词汇变量。
http://www.gnu.org/software/emacs/manual/html_node/elisp/Setting-Variables.html
特殊表格:
setq
[符号 表格] ...这种特殊形式是更改变量值的最常用方法。 (...)符号的当前绑定已更改。
(...)
功能:
set
符号 值此函数将值放入 symbol 的值单元格中。
(...)
当动态变量绑定生效时(默认值),
set
与setq
具有相同的效果,除了set
评估其符号参数而setq
} 才不是。但是当一个变量是词法绑定时,set
会影响其动态值,而setq
会影响其当前(词法)值。
如果我们将defvar
定义为a
作为全局变量,我们可以看到a
函数中对my-print-a
的所有引用都被动态绑定手册解释:
(eval
'(progn
(defvar a nil)
(setq a "global")
(let ((a "apple"))
(defun my-print-a ()
(print a) ; "banana"
(set 'a "by set")
(print a)) ; "by set"
(setq a "mature apple"))
(let ((a "banana"))
(my-print-a))
(print a)) ; "global"
t)