注意,用 load 加载没有编译的文件时这个变量必须写在文件中第一个換行符前面(即第一行)才能生效,并且文件的开头必须是注释 ;
或者 #!
),而且前面不应该有如空格等其他字符。因为 emacs 解释器代码没法在读到文件后面再切换 lexical binding,并且本身除了编程成在文件开头检查 lexical binding 变量外,对注释内容是完全忽略的。如果写在文件结尾,这种情况是不会生效的。这是一个已知 bug,之前在论坛里通过 @shynur 发现的 在 .emacs 中开启词法绑定的作用? - #4,来自 LdBeth
https://mail.gnu.org/archive/html/bug-gnu-emacs/2023-06/msg01331.html
只有在 byte compile 时,因为会把整个文件读取到 buffer 里写在后面的这个变量才能生效。
这个 bug 最后没有完全解决,因为需要重新设计解释器,只能加个编译器警告了事,但是实际上会影响的是解释器
举几个例子,这些写法虽然在第一行,而且 hack-local-variables
能认出来,但对于用 lisp_file_lexically_bound_p
的解釋器也是不行的
(let ((y 12)) (defun foo (x) (setq y x))) ;; -*- lexical-binding: t; -*-
(let ((y 12)) (defun foo (x) "-*- lexical-binding: t; -*-" (setq y x)))
然后点名批评 @include-yy
这个不是应该忽略的问题,只是实在没办法挡住头脑奇妙的人用不标准的写法,才勉强实现成 warning。