Comme le disent les autres réponses, c'est exactement ainsi que fonctionne defvar, mais vous pouvez le contourner, c'est clair après tout.
Vous pouvez redéfinir temporairement le fonctionnement de defvar si vous le souhaitez et pendant ce temps, rechargez les packages que vous souhaitez réinitialiser.
J'ai écrit une macro où lors de l'évaluation du corps, les valeurs de defvars seront toujours réévaluées.
(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)))))
Exemple d'utilisation:
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))
Remarque: ceci ne doit être utilisé que dans le but de réévaluer les defvars, car il ignore simplement les docstrings lors de la réévaluation. Vous pouvez modifier la macro pour prendre en charge la réévaluation qui applique également les docstrings, mais je vous laisse le soin de le faire.
Dans votre cas, vous pourriez faire
(with-forced-defvar-eval (require 'some-package))
Mais sachez ce que font ceux qui écrivent elisp en s'attendant à ce que defvar fonctionne comme spécifié, il se peut qu'ils utilisent defvar pour définir et setq dans une fonction init pour spécifier la valeur, de sorte que vous pouvez finir par des variables nulles que vous n'avez pas l'intention mais c'est probablement rare.
Mise en œuvre alternative
En utilisant cela, vous pouvez simplement redéfinir defvar globalement et contrôler s'il définira ou non la valeur du symbole sur l'argument INIT-VALUE même si le symbole est défini en modifiant la valeur du nouveau defvar-always-reeval-values
symbole.
;; 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
puis réévaluer le code dans le tampon.