【问题标题】:What are the new rules for variable scoping in Emacs 24?Emacs 24 中变量作用域的新规则是什么?
【发布时间】:2011-12-01 01:48:53
【问题描述】:

Emacs 24 现在具有词法范围的变量。当然,它还具有动态范围的变量。既然它两者都有,我对变量何时具有哪种范围感到很困惑。有一个lexical-binding 变量控制何时启用词法绑定,我想我读到了一些关于defvar 现在声明一个动态范围的变量,但总的来说我很迷茫。 Emacs 24 的新范围规则是否有很好的解释?或者换一种说法,当我查看为 Emacs 24 编写的 Emacs Lisp 代码中的一个变量时,我如何知道该变量正在使用什么范围?

【问题讨论】:

  • 如果您已安装 Emacs 24,则此信息可在信息中找到。打开“Emacs Lisp”节点并点击i 搜索索引。
  • 我同时安装了 23 和 24,所以有点混乱。有“Elisp”和“Elisp (emacs-snapshot)”条目。我现在看到了。另外,我有时会忘记 Emacs 是一个文档很好的项目,可能不是在没有足够文档的情况下合并主要新功能的类型。

标签: emacs elisp lexical-scope dynamic-scope emacs24


【解决方案1】:

假设在 Emacs 中逐步评估某些代码(因为您刚刚执行了C-x C-e,或者因为正在加载 Emacs Lisp 文件,或者因为正在运行来自钩子的函数等),并且Emacs 即将在该代码中评估my-abc。也许my-abc 是该代码中的一个局部变量,或者它没有被声明,或者它有一些全局值,等等。无论如何,当前步骤是评估my-abc。此时,Emacs 只检查两件事来决定是否使用词法范围评估 my-abc

Emacs 检查的第一件事是“my-abc 是一个特殊变量吗?”。如果 (defvar my-abc ...)(defcustom my-abc ..) 或 etc 在过去的任何时候运行,则该问题的答案是肯定的。可能(defcustom my-abc ..) 在加载其他一些 Emacs Lisp 文件时运行,或者您在暂存缓冲区中评估了一些包含 (defvar my-abc ...) 的代码,或者可能没有。如果出于某种原因答案是肯定的,此时 Emacs 将使用动态范围评估 my-abc

如果答案是否定的,那么 Emacs 会检查第二件事,即 (A)“我 (Emacs) 正在执行的这段代码(包含 my-abc 的使用)在哪里?”。这不是(B)“现在的缓冲区是什么?”。如果您只是在缓冲区上按了 Cx Ce,比如说 foo.el,并且如果您按 Cx ce 的表达式包含对在 mah-stuff.el 中定义的名为 mah-hello 的函数的调用,并且如果包含 mah-hello 函数体调用在my-stuff.el 中定义的名为my-hello 的函数,并且如果my-hello 的函数体包含使用名为my-abc 的变量,那么当Emacs 最终执行my-hello 时大约在那里评估my-abc,当Emacs问问题A时,它会回答my-stuff.el给自己。不是包含起始表达式的缓冲区foo.el

然后 Emacs 会询问“my-stuff.el 是一个词法范围的缓冲区,换句话说,lexical-binding 在那个缓冲区上是否为真?”。如果是,Emacs 使用词法范围评估 my-abc,否则使用动态范围。

一些更新:另外,当代码被引用为数据然后传递给eval 函数时,(A) 的答案将不是缓冲区。尽管如此,就好像eval 组成了一个假想的缓冲区来放置代码,并将该缓冲区的缓冲区本地值lexical-binding 设置为传递给eval 的第二个参数。 (A) 的答案是不是包含“eval”调用的缓冲区。它是虚构的缓冲区。

对于 Lisp 宏,当一些宏扩展代码正在运行时,就好像扩展代码被写入包含调用宏的代码的缓冲区。因此,在这种情况下,(A) 的答案不是定义宏的缓冲区,而是调用宏的代码所在的缓冲区。

【讨论】:

  • 很好的解释。谢谢!
【解决方案2】:

手册是权威来源。从这里开始:

C-hig (elisp) Variable Scoping RET

我最初在此答案中引用了手册,但该信息(可追溯到 Emacs 24.0.90.1)稍微过时了。最好从 Emacs 内部阅读手册,以便信息对于您正在使用的版本是正确的。

如果你特别想在网页上阅读,目前的版本是:
http://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Scoping.html

【讨论】:

    猜你喜欢
    • 2018-04-19
    • 1970-01-01
    • 2021-09-06
    相关资源
    最近更新 更多