4

The situation I have is this. First, I run

(require 'prolog)

...which loads the system's default version of prolog.el, and makes the variable prolog-mode-version available. It has value "1.22".

Now, I know that my personal copy of this package, in /path/to/my/own/private/prolog.el, starts with

(defvar prolog-mode-version "1.25"
  "Prolog mode version number")

So I run

(load "/path/to/my/own/private/prolog.el")

...expecting that, after doing so, prolog-mode-version will now have value "1.25".

This is not what happens, though: according to describe-variable at least, the value of prolog-mode-version is still "1.22".


What must I need to do to (re-)load 'prolog from /path/to/my/own/private/prolog.el?

11
  • 3
    defvars (and defcustoms, which use defvar) can only be defined once. To re-evaluate a defvar, place point over it and eval-defun (C-M-x). Commented Feb 27, 2017 at 17:22
  • @TianxiangXiong: thanks! How can I do what you describe programmatically?
    – kjo
    Commented Feb 27, 2017 at 17:23
  • 3
    Not easily. See: emacs.stackexchange.com/questions/2298/… Commented Feb 27, 2017 at 17:26
  • @TianxiangXiong: Thanks again. Come to think of it, I need to eval the whole file, since there's a ton of other defvars in there... I never expected this to be such a nightmare...
    – kjo
    Commented Feb 27, 2017 at 17:31
  • If you're running your own version of the package, why not stop using the system-provided one? Commented Feb 27, 2017 at 17:31

2 Answers 2

7

You can unload the system prolog mode first, this unbinds all its variables, so that the new defvar init-forms will take effect:

(require 'prolog)
(when (version< prolog-mode-version "1.25")
  (unload-feature 'prolog)
  (load "/path/to/my/own/private/prolog.el"))

Note that unload-feature is not a commonly used function, so it's possible you may hit some bugs. Most packages are not written with unloading in mind. Glancing at prolog.el, I don't see anything that should be a problem though (examples of potentially "problematic" forms would be side-effecting top-level calls, apart from the usual defun, defvar, defconst, defcustom, etc).

3
  • +1 for mentioning the caveat "Most packages are not written with unloading in mind."
    – Drew
    Commented Feb 27, 2017 at 21:21
  • Thanks! I noticed that, although I had used (require 'prolog) in my original question, in your answer you used (require 'prolog-mode) instead. Was there a particular reason for that change?
    – kjo
    Commented Mar 1, 2017 at 12:18
  • 1
    @kjo no, that was a mistake on my part, fixed now.
    – npostavs
    Commented Mar 1, 2017 at 14:46
3

As an alternative to unload-feature, you could use this to check the version of the default package without actually loading the code:

(let ((version (with-temp-buffer
                 (insert-file (find-library-name "prolog"))
                 (re-search-forward "(defvar prolog-mode-version \"\\([^\"]+\\)")
                 (string-to-number (match-string 1)))))
  (if (< version 1.25)
      (load "/path/to/my/own/private/prolog.el")
    (require 'prolog)))

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.