Как работать без замыканий в динамическом копировании Emacs lisp

Я знаю, что 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 не определено во время работы лямбды, я придумал это, чтобы форсировать оценку p в контексте списка, а не когда лямбда работает.

(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 ответ

Решение

Я бы сделал это так, если бы хотел сохранить привязки в списке, как вы. Я на самом деле предпочитаю разобрать 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))))) 
Другие вопросы по тегам