Советы по надежному определению переменных
При определении переменной, значением которой является функция или список функций, используйте имя, оканчивающееся на «-функция» или «-функции» соответственно.
Существует несколько других соглашений об именах переменных; вот полный список:
- ‘…-ключ’
-
Переменная является обычным ключом (см. Ключи).
- ‘…-функция’
-
Значение является функцией.
- ‘…-функции’
-
Значение является списком функций.
- ‘…-форма’
-
Значение является формой (выражением).
- ‘…-формы’
-
Значение является списком форм (выражений).
- ‘…-предикат’
-
Значение является предикатом — функцией одного аргумента, возвращающей значение отличное от
nilдля успеха иnilдля неудачи. - ‘…-флаг’
-
Значение значимо только в том, является ли оно
nilили нет. Поскольку такие переменные часто со временем приобретают больше значений, это соглашение не очень рекомендуется. - ‘…-программа’
-
Значение — имя программы.
- ‘…-команда’
-
Значение — вся командная оболочка.
- ‘…-переключатели’
-
Значение задает параметры для команды.
- ‘префикс--…’
-
Переменная предназначена для внутреннего использования и определена в файле префикс.el. (Код Emacs, предоставленный до 2018 года, может следовать другим соглашениям, которые постепенно отменяются.)
- ‘…-внутренний’
Переменная предназначена для внутреннего использования и определена в коде C. (Код Emacs, предоставленный до 2018 года, может следовать другим соглашениям, которые постепенно отменяются.)
При определении переменной всегда нужно учитывать, следует ли отмечать её как безопасную или рискованную; см. Локальные переменные файла.
При определении и инициализации переменной, хранящей сложное значение (например, карту ключей с привязками в ней), лучше всего поместить все вычисления значения в defvar, как в этом примере:
(defvar my-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "\C-c\C-a" 'my-command)
…
map)
docstring)
Этот метод имеет несколько преимуществ. Во-первых, если пользователь завершит работу во время загрузки файла, переменная будет либо по-прежнему неинициализированной, либо инициализированной должным образом, никогда не в промежуточном состоянии. Если она всё ещё неинициализированная, повторная загрузка файла инициализирует её должным образом. Во-вторых, повторная загрузка файла после инициализации переменной не изменит её; это важно, если пользователь запустил хуки для изменения части содержимого (например, для перепривязки клавиш). В-третьих, вычисление defvar формы с помощью C-M-x полностью переинициализирует карту.
Размещение такого большого кода в defvar форме имеет один недостаток: это отделяет строку документации от строки, в которой указано имя переменной. Вот безопасный способ избежать этого:
(defvar my-mode-map nil
docstring)
(unless my-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "\C-c\C-a" 'my-command)
…
(setq my-mode-map map)))
Это имеет все те же преимущества, что и размещение инициализации внутри defvar, за исключением того, что вам нужно нажать C-M-x дважды, на каждой форме, если вы хотите переинициализировать переменную.
Copyright © 1990-1996, 1998-2022 Free Software Foundation, Inc.
Licensed under the GNU GPL license.
https://www.gnu.org/software/emacs/manual/html_node/elisp/Tips-for-Defining.html