Spec-Zone.ru › Elisp

Советы по надежному определению переменных

При определении переменной, значением которой является функция или список функций, используйте имя, оканчивающееся на «-функция» или «-функции» соответственно.

Существует несколько других соглашений об именах переменных; вот полный список:

‘…-ключ’

Переменная является обычным ключом (см. Ключи).

‘…-функция’

Значение является функцией.

‘…-функции’

Значение является списком функций.

‘…-форма’

Значение является формой (выражением).

‘…-формы’

Значение является списком форм (выражений).

‘…-предикат’

Значение является предикатом — функцией одного аргумента, возвращающей значение отличное от 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API