Как работать без замыканий в динамическом копировании 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)))))