2

Below is an example of the situation described in the question's title, using the variable prolog-mode-version as test case.

If my Emacs init file consists of just the code shown below:

(defun show-pmv (hook-name)
  (let ((pmv (if (boundp 'prolog-mode-version)
                 prolog-mode-version
               "undefined")))
    (message "%s: prolog-mode-version: %s" hook-name pmv)))

(add-hook 'after-init-hook    (lambda () (show-pmv "after-init")))
(add-hook 'emacs-startup-hook (lambda () (show-pmv "emacs-startup")))
(add-hook 'window-setup-hook  (lambda () (show-pmv "window-setup")))

(setq inhibit-startup-screen t)
(switch-to-buffer "*Messages*")

...and I start up Emacs, my *Messages* buffer contains the following

after-init: prolog-mode-version: undefined
For information about GNU Emacs and the GNU system, type C-h C-a.
emacs-startup: prolog-mode-version: undefined
window-setup: prolog-mode-version: undefined

...but if, right after startup, I inspect the value of prolog-mode-version (using C-h v), I get a non-void value ("1.22").

The variable prolog-mode-version is not an isolated case. In fact, many other symbols defined in prolog.el seem to be available right after startup, even though my init file does not load/require this package.

I find this extremely confusing.

Why do symbols that were void during startup become suddenly defined right after startup?

Conversely, is there some way for my init file to access the value of prolog-mode-version?

(Related.)

  • 1
    Are you using Emacs version 26.0.50? There is a new feature which autoloads libraries during completion, so your C-h v might be triggering the load. See also Bug#25552. – npostavs Feb 27 '17 at 16:01
  • Does anything change if, before your calls to #'add-hook, you put (require 'prolog-mode)? – zck Feb 27 '17 at 16:17
  • @zck: no; the totality of my init file is what I show in the post. – kjo Feb 27 '17 at 16:52
2

It's autoloaded. Or rather, I should say that the library is autoloaded, so that the variable only starts existing once you've caused Emacs to actually load the library (usually by calling a function or using a macro from the library).

However, autoloading isn't available when processing the init files. Instead, explicitly load the library with (require 'prolog).

Autoloading is a moderately complex subject, so I recommend reading section 15.5 of the Elisp manual. Actually, all of chapter 15 is quite interesting.

  • autoloading is available when processing init files, e.g., if you put (run-prolog) in your init file, the prolog library will be loaded. – npostavs Feb 27 '17 at 17:42
  • The original post states that the behaviour was tested also in 'after init' so I don't think this answer actually explains anything. Or does it? I'd like to see a reply to npostavs' comment (wrt Emacs version) however. – YoungFrog Feb 27 '17 at 19:10
3

Symbols defined only in the prolog library will be bound only if that library has actually been loaded. You can establish when it is being loaded by invoking the debugger:

(add-hook 'after-load-functions 'my-load-debug)

(defun my-load-debug (file)
  (when (string= "prolog" (file-name-base file))
    (debug)))

or just:

(eval-after-load "prolog" '(debug))

If there are autoload definitions for the symbols, then they would be bound (without loading the prolog library), as soon as the appropriate loaddefs.el (or equivalent) file defining those autoloads has been loaded.

Note that C-h v and C-h f will indicate when a given variable or function is an autoload definition.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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