Tak jak inne odpowiedzi mówią, tak działa defvar, ale można to obejść, w końcu jest elisp.
Możesz tymczasowo zmienić sposób działania defvar, jeśli chcesz, i w tym czasie ponownie załaduj pakiety, które chcesz zresetować.
Napisałem makro, w którym podczas oceny ciała wartości defvars zawsze będą przewartościowane.
(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)))))
Przykładowe użycie:
plik_a.el
(defvar my-var 10)
plik_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))
Uwaga: należy tego używać wyłącznie w celu ponownej oceny defvarów, ponieważ po prostu ignoruje ona dokumenty podczas ponownej oceny. Możesz zmodyfikować makro w celu obsługi ponownej oceny, która dotyczy również dokumentów, ale pozostawię to tobie.
W twoim przypadku możesz to zrobić
(with-forced-defvar-eval (require 'some-package))
Ale wiedz, co robią ci, którzy piszą elisp, oczekując, że defvar będzie działał zgodnie ze specyfikacją, może być tak, że używają defvar do definiowania i setq w jakiejś funkcji init, aby określić wartość, więc możesz skończyć na zerowych zmiennych, których nie zamierzasz, ale jest to prawdopodobnie rzadkie.
Alternatywne wdrożenie
Za pomocą tego możesz po prostu przedefiniować globalnie defvar i kontrolować, czy ustawi wartość symbolu na wartość INIT-VALUE arg, nawet jeśli symbol jest zdefiniowany przez zmianę wartości nowego defvar-always-reeval-values
symbolu.
;; 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
a następnie ponownie ocenić kod w buforze.