Работа с «Предупреждение: присвоение свободной переменной», когда определенные библиотеки могут отсутствовать в дизайне

12

Байтная компиляция моего режима:

(defun dict-setup-expansions ()
  "Add `dict-mode' specific expansions."
  (set (make-local-variable 'er/try-expand-list) (list #'dict-mark-article)))

дает предупреждение:

Warning: assignment to free variable `er/try-expand-list'

Это нормальная ситуация, потому что er/try-expand-listопределяется в externa; библиотека, expand-regionкоторая находится на http://elpa.gnu.org

Мой режим регистрирует расширение для expand-regionбиблиотеки, но можно запустить мой режим без expand-regionрежима.

Я думаю, что правильный способ справиться с предупреждением - добавить объявление:

(defvar er/try-expand-list)

defvar документы говорят:

The `defvar' form also declares the variable as "special",
so that it is always dynamically bound even if `lexical-binding' is t.

Я использую -*- lexical-binding: t -*-. Означает ли это, что без defvarпеременной er/try-expand-listбудет в лексической области, и у меня есть реальная ошибка?

gavenkoa
источник
2
Примечание: вы не должны цитировать символ в (defvar er/try-expand-list).
ЖанПьер
@JeanPierre Исправлено.
gavenkoa

Ответы:

10

Нет, setи setqне объявляйте лексические переменные. Только letделает. Если бы вы использовали letздесь, у вас была бы ошибка, но это нормально. Предупреждение существует главным образом для обнаружения опечаток при использовании динамических переменных.

Чтобы убрать предупреждение, используйте defvarкак в вашем вопросе, но не ставьте в кавычки символ.

lunaryorn
источник
Является ли упаковка в eval-when-compileизлишне просто defvar? Я не вижу предупреждения без eval-when-compile. Кажется, что eval-when-compileэто необходимо, если использовать активный код, например (require ...)...
gavenkoa
3
Упаковка defvar будет излишней.
lunaryorn