使用let-bound变量渗透`set-process-sentinel`层次结构

law*_*ist 6 emacs elisp lexical-scope

我从来没有能够提出一种方法来通过函数开始时定义的set-process-sentinel let-bound变量来渗透层次结构- 只有缓冲区局部或全局变量可以穿透它.允许绑定变量可以达到第一个,但是只要它们可以穿透而不会因为被识别而被拒绝 - 在函数开始时定义的 let-bound变量似乎无法穿透开始的部分与.任何人都可以想到一种方法,包括穿透嵌套的哨兵,如下例所示?start-process(lambda (p e) . . .

(set-process-sentinel 
  (start-process
    "my-process-name-one"
     "*OUTPUT-BUFFER*"
    "/path/to/executable"
    "argument-one"
    "argument-two"
    "argument-three")
  (lambda (p e) (when (= 0 (process-exit-status p))
    (set-process-sentinel 
      (start-process
        "my-process-name-two"
        nil ;; example of not using an output buffer
        "/path/to/executable"
        "argument-one"
        "argument-two"
        "argument-three")
      (lambda (p e) (when (= 0 (process-exit-status p))
        (set-process-sentinel 
          (start-process . . . ))))))))
Run Code Online (Sandbox Code Playgroud)

leg*_*cia 7

问题是Emacs Lisp变量绑定默认是动态的.也就是说,在评估函数时,不会在定义函数的环境中查找绑定变量,而是在调用函数的环境中查找.

Emacs 24或更高版本本身支持词法绑定(即函数看到绑定在函数定义周围的变量),但由于它改变了现有代码的语义,因此需要显式启用它.通常,这是通过将文件局部变量设置添加到文件的第一行来完成的.el:

;; -*- lexical-binding: t; -*-
Run Code Online (Sandbox Code Playgroud)

另一种方法是lexical-letcl库中使用.这也适用于早期的Emacs版本.请注意,通过这种方式,您可以明确指定哪些变量应该具有词法绑定,因此代码(例如(lexical-let ((foo foo)) ...)并非罕见)foo是一个需要"转移"到函数中的现有变量.