Emacs 24中变量作用域的新规则是什么?
Emacs 24现在有词汇范围的变量。当然,它还有动态范围的变量。既然两者都有了,我就很困惑变量什么时候会有什么样的作用域。有一个Emacs 24中变量作用域的新规则是什么?,emacs,elisp,lexical-scope,dynamic-scope,emacs24,Emacs,Elisp,Lexical Scope,Dynamic Scope,Emacs24,Emacs 24现在有词汇范围的变量。当然,它还有动态范围的变量。既然两者都有了,我就很困惑变量什么时候会有什么样的作用域。有一个lexicalbinding变量控制何时启用lexicalbinding,我想我读了一些关于defvar的内容,现在声明了一个动态范围的变量,但总的来说我很迷茫。Emacs 24的新范围规则有什么好的解释吗?或者换句话说,当我查看为Emacs 24编写的Emacs Lisp代码中的变量时,如何判断该变量使用的范围?手册是最终的源代码。从这里开始: C-hig(elis
lexicalbinding
变量控制何时启用lexicalbinding,我想我读了一些关于defvar
的内容,现在声明了一个动态范围的变量,但总的来说我很迷茫。Emacs 24的新范围规则有什么好的解释吗?或者换句话说,当我查看为Emacs 24编写的Emacs Lisp代码中的变量时,如何判断该变量使用的范围?手册是最终的源代码。从这里开始:
C-hig(elisp)变量作用域
我最初在回答中引用了手册,但该信息(可追溯到Emacs 24.0.90.1)有点过时。最好从Emacs内部阅读该手册,以便信息与您使用的版本相符
如果您特别想在网页上阅读,当前版本为:
假设在Emacs中一步一步地评估某些代码(要么是因为您刚刚执行了C-x C-e
,要么是因为正在加载Emacs Lisp文件,要么是因为正在运行一个钩子函数,等等),Emacs将在该代码中评估my abc
。可能my abc
是该代码中的一个局部变量,或者它没有声明,或者它有一些全局值,等等。无论如何,当前步骤是计算my abc
。此时,Emacs只检查两件事,以决定是否使用词法范围评估myABC
Emacs检查的第一件事是“我的abc是否是一个特殊变量?”。如果(defvar my abc…
或(defcustom my abc…)
或etc在过去的任何时候运行,则该问题的答案是肯定的。可能是在加载其他一些Emacs Lisp文件时运行了(defcustom my abc…)
,或者您在暂存缓冲区上评估了一些包含(defvar my abc…
)的代码,也可能不是。如果出于任何原因,答案为“是”,此时Emacs将使用动态范围评估my abc
如果答案是否定的,那么Emacs检查第二件事,即(A)“我(Emacs)正在处理的代码(包含使用my abc
)在哪里?”。这不是(B)“当前缓冲区是什么?”。如果您刚刚在缓冲区上按了C-x C-e,比如说foo.el
,如果您按下C-x C-e的表达式包含对名为mah hello
的函数的调用,该函数在mah stuff.el
中定义,如果mah hello
函数体包含对名为my hello
的函数的调用,该函数在my stuff.el
中定义,并且如果my hello
的函数体包含名为my abc
的变量的使用,然后,当Emacs最终开始执行my hello
,然后在那里评估my abc
时,当Emacs问问题A时,它对自己回答my stuff.el
。不是包含起始表达式的缓冲区foo.el
然后Emacs问“是mystuff.el
一个词汇范围的缓冲区,换句话说,lexicalbinding
在该缓冲区上是真的吗?”。如果是,Emacs使用词法作用域计算MyABC
,否则使用动态作用域
一些更新:另外,当代码作为数据引用,然后传递到eval
函数时,(A)的答案将不是缓冲区。不过,这就好像eval
组成了一个虚构的缓冲区来放置代码,并将该缓冲区的词法绑定的缓冲区本地值设置为传递给eval
的第二个参数。(A)的答案不是包含“eval”调用的缓冲区。它是假想的缓冲区
对于Lisp宏,当运行某些宏扩展代码时,就好像扩展代码被写入包含调用宏的代码的缓冲区一样。因此,本例中(A)的答案不是定义宏的缓冲区,而是调用宏的代码所在的缓冲区。如果您安装了Emacs 24,则此信息可在信息中找到。打开“Emacs Lisp”节点,点击i
搜索索引。我已经安装了23和24,所以有点混乱。有“Elisp”和“Elisp(emacs快照)”条目。我现在看到了。此外,我有时忘记了Emacs是一个有很好文档的项目,在没有足够文档的情况下,它可能不是合并主要新特性的类型。谢谢