다른 답변에서 알 수 있듯이 이것은 defvar이 작동하는 방식 일뿐이지만 해결할 수 있습니다.
원하는 경우 defvar의 작동 방식을 임시로 재정의 할 수 있으며이 시간 동안 재설정하려는 패키지를 다시로드하십시오.
나는 신체를 평가하는 동안 defvars 값이 항상 재평가되는 매크로를 작성했습니다.
(defmacro my-fake-defvar (name value &rest _)
"defvar impersonator that forces reeval."
`(progn (setq ,name ,value)
',name))
(defmacro with-forced-defvar-eval (&rest body)
"While evaluating, any defvars encountered are reevaluated"
(declare (indent defun))
(let ((dv-sym (make-symbol "old-defvar")))
`(let ((,dv-sym (symbol-function 'defvar)))
(unwind-protect
(progn
(fset 'defvar (symbol-function 'my-fake-defvar))
,@body)
(fset 'defvar ,dv-sym)))))
사용법 예 :
file_a.el
(defvar my-var 10)
file_b.el
(with-forced-defvar-eval
(load-file "file_a.el")
(assert (= my-var 10))
(setq my-var 11)
(assert (= my-var 11)
(load-file "file_a.el")
(assert (= my-var 10))
참고 : 이것은 재평가시 docstring을 무시하므로 defvar를 재평가 할 목적으로 만 사용해야합니다. docstring도 적용하는 재평가를 지원하기 위해 매크로를 수정할 수는 있지만 그 내용은 그대로 두겠습니다.
귀하의 경우에는 할 수 있습니다
(with-forced-defvar-eval (require 'some-package))
그러나 elisp를 작성하는 사람들은 defvar이 지정된대로 작동하기를 기대하므로 defvar을 사용하여 값을 지정하기 위해 init 함수에서 일부 q를 정의하고 setq를 사용할 수 있습니다. 이것은 아마도 드물다.
대체 구현
이를 사용하면 defvar를 전체적으로 재정의하고 새 defvar-always-reeval-values
심볼 의 값을 변경하여 심볼이 정의 된 경우에도 심볼 값을 INIT-VALUE arg로 설정할지 여부를 제어 할 수 있습니다 .
;; save the original defvar definition
(fset 'original-defvar (symbol-function 'defvar))
(defvar defvar-always-reeval-values nil
"When non-nil, defvar will reevaluate the init-val arg even if the symbol is defined.")
(defmacro my-new-defvar (name &optional init-value docstring)
"Like defvar, but when `defvar-always-reeval-values' is non-nil, it will set the symbol's value to INIT-VALUE even if the symbol is defined."
`(progn
(when defvar-always-reeval-values (makunbound ',name))
(original-defvar ,name ,init-value ,docstring)))
;; globally redefine defvar to the new form
(fset 'defvar (symbol-function 'my-new-defvar))
makunbound