如何在Emacs lisp动态范围中不使用闭包工作

时间:2013-11-09 14:37:27

标签: closures elisp dynamic-scope

我知道Emacs 24引入了词法范围;这很棒,但我一直在使用词法范围,我试图从不同的角度看动态范围。

最初我只是做了我将要做的事情,依靠封闭:

(add-hook 'cider-mode-hook 
  (lambda () 
    (dolist (p '(("M-l" . cider-load-current-buffer)
         ("M-e" . cider-eval-last-expression)))
      (local-set-key 
       (kbd (car p)) 
       (lambda () (interactive) (save-buffer) (cdr p))))))

在最终理解为什么p在lambda运行时未定义时,我想出了这个来强制在dolist的上下文中评估p而不是lambda运行时。

(add-hook 'cider-mode-hook 
  (lambda () 
    (dolist (p '(("M-l" . cider-load-current-buffer)
         ("M-e" . cider-eval-last-expression)))
      (local-set-key 
       (kbd (car p)) 
       (cons 'lambda `(() (interactive) (save-buffer) (funcall (quote ,(cdr p)))))))))

这是解决问题的经典解决方案,没有闭包和词法范围吗?

1 个答案:

答案 0 :(得分:1)

如果我想将绑定保存在像你这样的列表中,我会这样做。 我实际上更喜欢为每个命令拼出local-set-key

(defun save-before-call (f)
  `(lambda()
     (interactive)
     (save-buffer)
     (funcall #',f)))

(add-hook 'cider-mode-hook
  (lambda ()
    (mapc (lambda(x)(local-set-key
                     (kbd (car x))
                     (save-before-call (cdr x))))
          '(("M-l" . cider-load-current-buffer)
            ("M-e" . cider-eval-last-expression)))))