Elisp: “defvar” Doesn't Override
there's this annoying problem in elisp. “defvar” does not override if the variable already has a value.
for example, run this:
(defvar yy 4 "DOCSTRING") (defvar yy 3 "DOCSTRING") (message "%d" yy)
the result is still 4.
what this means is that if you are actively developing a package, you can't reload your file and expect it to work.
The emacs behavior is documented:
(defvar SYMBOL &optional INITVALUE DOCSTRING) … The optional argument INITVALUE is evaluated, and used to set SYMBOL, only if SYMBOL's value is void. If SYMBOL is buffer-local, its default value is what is set; buffer-local values are not affected. If INITVALUE is missing, SYMBOL's value is not set.
here's a way to avoid the problem. When you write a mode, it's better to give the initial value of “nil” when using “defvar”, then set it immediately after it. Like this:
(defvar yy nil "DOCSTRING") (setq yy 3 )
this way, when reloading, the new value will take place.
defvar vs defcustom
Jack Donohue told me that the reason it's that way because users might set the var in their init file so that reloading a mode won't over-ride user's customization.
in the end, i think whether you should just use
defvar or use
setq afterward depends on what you are using the variable for. Modern elisp probably should use
defcustom for vars for users to set.