Почему код в with-temp-buffer жалуется на переменную void, когда в «родительском» буфере есть локальная переменная с тем же именем, которое я связал? - PullRequest
7 голосов
/ 25 января 2012

Я просто целую вечность выяснял, что не так с моим кодом. Он хорошо работал в тестах ert unit, но потерпел неудачу, когда я запустил его в более широком контексте. Вот пример кода, который работал:

(defun func (my-var)
  (with-temp-buffer
    (message my-var)))

(func "z")

Это печатает z, как ожидалось. Теперь я писал основной режим, который имел некоторые локальные для буфера переменные. Одним из них был мой вар. Этот код демонстрирует мою проблему:

(make-local-variable 'my-var)
(setq my-var "y")

(defun func (my-var)
  (with-temp-buffer
    (message my-var)))

(func "z")

Выход? Там нет ни одного, только это сообщение об ошибке:

eval-buffer: Symbol's value as variable is void: my-var

В этом примере легко увидеть, что локальная переменная буфера как-то мешает динамически связанному my-var. Это было не так просто, когда у меня было несколько экранов кода: -)

Итак, мой вопрос: что здесь на самом деле происходит? Очевидно, что временный буфер каким-то образом наследует переменную из «родительского» буфера, но почему он имеет значение void? Я бы понял, получит ли оно значение "y" как-то, но такое поведение для меня похоже на ошибку.

PS. Я использую последние версии Aquamacs

1 Ответ

3 голосов
/ 25 января 2012

Пара вещей.

Во-первых, ваш код не работает как есть. Вы должны попробовать это в новом вызове Emacs. Как только вы это сделаете, вы увидите, что вам нужно передать make-local-variable символ, например:

(make-local-variable 'my-var)

Обратите внимание на `` `.

Во-вторых, вы определили локальную переменную буфера, имеющую то же имя, что и параметр func, поэтому любой ответ должен различать их.

Итак, вот моя очищенная версия вашего примера:

(make-local-variable 'my-var)
(setq my-var "y")

(defun func (my-param)
  (with-temp-buffer
(message my-param)))

(func "z")

И это прекрасно работает.

Что заставляет меня поверить, что ошибка, которую вы видите, связана с вызовом make-local-variable без кавычки перед my-var.

Оригинальный ответ предоставлен ниже, хотя он не решает проблему:


Ознакомьтесь с документацией для make-local-variable. Строка документа:

make-local-variable - это интерактивная встроенная функция в `C source код».

(make-local-variable VARIABLE)

Сделать VARIABLE отдельным значением в текущем буфере. Другой буферы будут продолжать использовать общее значение по умолчанию. (The локальное значение буфера VARIABLE начинается с того же значения VARIABLE ранее имел. Если переменная была недействительной, она остается недействительной.) Возврат ПЕРЕМЕННЫЕ.

Ключевой частью для вас является последнее предложение. If the variable was void, it remains void.

Это означает, что, если он еще не был определен глобально, он все еще не определен глобально. Другими словами, он имеет привязку только в тех буферах, в которых он был явно установлен.

Если вы хотите, чтобы оно имело глобальное значение, используйте setq-default примерно так:

(setq-default my-var "some-default-value")
...