有没有感觉Emacs25中的symbol-value函数用起来很混乱

根据symbol-value的说明,当开启静态作用域时,只能取到全局环境下symbol的值,而不是当前作用域下symbol的值

但是

;; -*- lexical-binding: t; -*-

(defvar v "global")

(defun test ()
  (let ((v "let"))
    (symbol-value (intern "v"))))       

(test)                                ;let


(defun test-1 ()
  (let ((a "let"))
    (symbol-value (intern "a"))))

(test-1)                              ;(void-variable a)

感觉整个人都不好了,不知道是不是Emacs25的BUG?Emacs24有没有这个呢?

确实很奇怪。 。。 感觉第二个测试例的输出结果无法理解。。

第一个测试的结果也跟doc-string说明中的不一样…

可能是由于 defvar 比较特殊,你可以把它换成 setq 试一试:

In Emacs 24, defvar creates things called special variables. Special variables are dynamically scoped variables that will be bound dynamically even in lexically scoped functions.

引用来源:

https://yoo2080.wordpress.com/2011/12/31/lexical-scoping-and-dynamic-scoping-in-emacs-lisp/

果然是这样,换成setq第一个例子就是返回"global"了

现在还有个问题,在第二个例子中,会直接报错. 那么有没有什么方法是可以让它返回"let"呢?

换句话说,希望能够做到:

(defun test-1 ()
  (let ((a "let"))
    (some-function-like-symbol-value (intern "a"))))

(test-1)                              ;希望它能返回"let"

我觉得并没有什么好办法。。。

symbol-value (eval, set 类似) 只能处理 dynamic scoping 的变量,所以

  • 要么不要开启 lexical-binding
  • 要么用 defvar 定义成 dynamic scoping 的 special variable,就像你的第一个 test 函数一样