LdBeth
22
给代码
让我猜一猜给我上强度是吧
(let ((fn (letrec ((x (lambda ()
(message ":P")
(remove-hook 'post-self-insert-hook x))))
x)))
(custom-set-variables
'(post-self-insert-hook `(,@(when (boundp 'post-self-insert-hook)
post-self-insert-hook)
,fn))))
很简单,custom-set-variables
不会用词法作用域,也不会保留上下文。
Shynur
23
是的,给你上强度。(电脑不在身边,手机懒得打字)
这样:
(custom
‘(xxx-hook ’(,@(…)
,(let ((词法绑定 t))
(letrec 。。。
LdBeth
24
你加 let 在 custom-set-variables
的参数里面是 nop ,并不会达到你以为开启词法作用域的效果。
Shynur
25
对,我其实从一开始就是想问这个问题(我猜测是这样,但我不确定)。所以理由是什么?为什么是nop呢?
LdBeth
26
理由是 let 绑定了 lexical-binding 之前解释器已经把整个表达式的词法解析过程做完了,再怎么改变 lexical-binding 也不能改变已经用动态作用域做了解析的既成事实
就是我一开始给的思考题答案
和 TeX 的 catcode 关系是 TeX 不能改变已经 tokenized 部分的 catcode,所以想改变 catcode 要保证改变在开始 tokenize 需要 catcode 起作用的部分之前就完成。
custom-set-variables 调用 eval
来处理参数,并且不会由当前的 lexical-binding 影响,只会用动态作用域。
总之,认为 custom-set-variables 和 setq 在 lexical-binding = t 时行为一致是错误的。
2 个赞
Shynur
27
soga. 照这么说的话, 手写代码中的
(let ((lexical-binding xxx))
...)
都没啥实际作用是吧.
LdBeth
28
除了在 let body 里调用编译器之类的,lexical-binding
可以影响 byte-compile
的行为。
Shynur
29
你可以去 SE 回答这个问题吗? 然后我 accept 它. 如果你懒得回答得话, 那我去回答 (当然, 我会提供指向这里的链接).