Подтвердить что ты не робот

Каковы новые правила изменения переменных в Emacs 24?

В Emacs 24 теперь есть лексически измененные переменные. Разумеется, он также имеет динамически измененные переменные. Теперь, когда у него есть оба, я довольно смущен, когда переменная будет иметь какой-то объем. Там переменная lexical-binding, которая контролирует, когда включена лексическая привязка, и я думаю, что я что-то прочитал о defvar, объявляющем переменную с динамической областью, но в целом я довольно потерян. Есть ли хорошее объяснение где-то в Emacs 24 новых правилах? Или по-другому, когда я смотрю на переменную в Emacs Lisp код, написанный для Emacs 24, как я могу определить, какую область действия использует эта переменная?

4b9b3361

Ответ 1

Руководство является окончательным источником. Начать здесь:

C-h i g (elisp) Variable Scoping RET

Я изначально цитировал руководство в этом ответе, но эта информация (датированная Emacs 24.0.90.1) была немного устаревшей. Лучше прочитать руководство изнутри Emacs, чтобы информация была верна для используемой версии.

Если вам особенно хочется прочитать его на веб-странице, текущая версия:
http://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Scoping.html

Ответ 2

Скажем, что некоторый код оценивается пошагово в 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) am stepping?". Это не (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) в этом случае не является буфером, который определил макрос, но буфер, в котором находится код, называемый макросом.