buffer-local 的疑问

这是犄角旮旯里的黑魔法,研究这个感觉没什么意义。(虽然可以迫使你去读 Emacs 源代码……)

第一次运行输出

Making foo buffer-local while locally let-bound!
This is a variable!
This is a variable!

首先 make-local-variable 发现 foo 不是一个 buffer-local variable,于是强行把 foo 这个符号指向一个新创建的 buffer-local variable

(progn
  (setq foo "I'm local variable!")      ; 全局
  (let ((foo "I'm local variable!"))    ; 局部
    ;; 创建 buffer-local variable,覆盖了 let 定义的 foo symbol
    (set (make-local-variable 'foo) "I'm buffer-local variable!")
    ;; 修改的是 buffer-local foo
    (setq foo "This is a variable!")
    (message "%s" foo))
  ;; 读到的是 buffer-local foo
  (message "%s" foo))

第二次运行输出

This is a variable!
I'm local variable!

是因为一个注释过的行为:

If the variable is already arranged to become local when set, this function causes a local value to exist for this buffer, just as setting the variable would do.

也就是代码相当于

(progn
  (setq foo "I'm local variable!")
  (let ((foo "I'm local variable!"))
    ;; (set (make-local-variable 'foo) "I'm buffer-local variable!")
    ;; 相当于
    (set 'foo "I'm buffer-local variable!")
    ;; 上下两句修改的是 let 定义的 foo
    (setq foo "This is a variable!")
    (message "%s" foo))
  ;; 读到的是 buffer-local foo
  (message "%s" foo))
3 个赞