В Emacs 24 теперь есть лексически измененные переменные. Разумеется, он также имеет динамически измененные переменные. Теперь, когда у него есть оба варианта, я довольно смущен, когда переменная будет иметь какой-то объем. Есть переменная lexical-binding
, которая контролирует, когда включена лексическая привязка, и я думаю, что я что-то прочитал о defvar
, объявляя переменную с динамической областью, но в целом я довольно потерян. Есть ли хорошее объяснение где-то в новых правилах Emacs 24? Или по-другому, когда я смотрю на переменную в коде Emacs Lisp, написанную для Emacs 24, как я могу определить, какую область использует эта переменная?Каковы новые правила изменения переменных в Emacs 24?
ответ
Руководство является окончательным источником. Начало здесь:
Chяг(elisp) Variable Scoping
RET
я первоначально процитировал руководство в этом ответе, но эта информация (уходящую в Emacs 24.0.90.1) был немного из Дата. Лучше прочитать руководство изнутри Emacs, чтобы информация была верна для используемой вами версии.
Если вы особенно хотите, чтобы прочитать его на веб-странице, текущая версия:
http://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Scoping.html
Допустим, что некоторые код оцениваемого шаг за шагом в Emacs (либо потому, что вы просто сделали C-x C-e
или из-за загружается файл Emacs Lisp или из-за того, что выполняется функция с крючка и т. д.), и что Emacs собирается оценить my-abc
внутри этого кода. Возможно, my-abc
является локальной переменной в этом коде или, возможно, не объявлен или, возможно, имеет какое-то глобальное значение и т. Д. В любом случае, текущий шаг - это оценка my-abc
. В этот момент Emacs проверяет только две вещи, чтобы решить, следует ли оценивать my-abc
с использованием лексического объема или нет.
Первое, что проверяет Emacs, это «my-abc
специальная переменная?». Ответ на этот вопрос - да, если (defvar my-abc ...)
или (defcustom my-abc ..)
или и т. Д. Был запущен в любой момент в прошлом. Может быть, (defcustom my-abc ..)
был запущен при загрузке какого-либо другого файла Emacs Lisp, или, может быть, вы оценили код, содержащий (defvar my-abc ...)
на буфере нуля, или, возможно, нет. Если по какой-либо причине ответ «да», Emacs в этот момент будет оценивать my-abc
с использованием динамической области.
Если ответ отрицательный, то Emacs проверяет вторую вещь, которая является (A) «где этот код (содержащий использование my-abc
), с которым я (Emacs) перешагивает?». Это не (B) «каков текущий буфер?». Если вы только что нажали Cx Ce в буфере, скажите foo.el
, и если выражение, нажатое Cx ce, содержит вызов функции с именем mah-hello
, которая определена в mah-stuff.el
, а если тело функции mah-hello
содержало вызов функции с именем my-hello
, которая определяется в my-stuff.el
, и если в теле функции my-hello
содержится использование переменной с именем my-abc
, тогда, когда Emacs в конечном итоге получают выполнение my-hello
, а затем собирается оценить my-abc
там, в тот момент, когда Emacs задает вопрос A, он отвечает my-stuff.el
к себе. Не буфер foo.el
, содержащий исходное выражение.
Затем Emacs спрашивает: «my-stuff.el
лексически ограниченный буфер, другими словами, равен lexical-binding
true на этом буфере?».Если да, Emacs оценивает my-abc
, используя лексическую область, в противном случае используя динамическую область.
Некоторое обновление: также, когда код цитируется как данные, а затем передается функции eval
, ответ на (A) не будет буфером. Тем не менее, это как если бы eval
составлял воображаемый буфер для размещения кода и устанавливал локальное значение буфера lexical-binding
для этого буфера для второго аргумента, переданного в eval
. Ответ на (A) равен , а не буфер, содержащий вызов `eval '. Это мнимый буфер.
Для макросов Lisp, когда выполняется некоторый макрорасширенный код, это как если бы расширенный код записывался в буфер, содержащий код, вызывающий макрос. Поэтому ответ на (A) в этом случае равен , а не буфер, определяющий макрос, но буфер, в котором находится код, называемый макросом.
Отличное объяснение. Благодаря! – killdash9
Если вы установили Emacs 24, эта информация доступна в информации. Откройте узел «Emacs Lisp» и нажмите «i», чтобы найти индекс. –
У меня установлены 23 и 24, поэтому это было немного запутанно. Были записи «Elisp» и «Elisp (emacs-snapshot)». Я вижу это сейчас. Кроме того, я иногда забываю, что Emacs является одним из проектов с хорошей документацией и, вероятно, не для того, чтобы объединить основные новые функции без соответствующей документации. –