Каковы новые правила для определения области видимости переменных в Emacs 24?

#emacs #elisp #lexical-scope #dynamic-scope #emacs24

#emacs #elisp #лексический охват #динамическая область действия #emacs24 #лексическая область #динамическая область

Вопрос:

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

Комментарии:

1. Если вы установили Emacs 24, эта информация доступна в информации. Откройте узел «Emacs Lisp» и нажмите i для поиска по индексу.

2. У меня установлены как 23, так и 24, так что это немного сбивало с толку. Были записи «Elisp» и «Elisp (emacs-snapshot)». Теперь я это вижу. Кроме того, я иногда забываю, что Emacs — один из проектов с хорошей документацией и, вероятно, не тот тип, который объединяет основные новые функции без соответствующей документации.

Ответ №1:

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

C-hig (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 ...) or (defcustom my-abc ..) или etc выполнялись в любой момент в прошлом. Возможно (defcustom my-abc ..) , был запущен при загрузке какого-либо другого файла Emacs Lisp, или, может быть, вы оценили какой-то код, содержащийся (defvar my-abc ...) в буфере scratch, или, может быть, нет. Если по какой-либо причине ответ положительный, Emacs на этом этапе выполнит оценку my-abc с использованием динамической области видимости.

Если ответ отрицательный, то Emacs проверяет второе, а именно (А) «где находится этот код (содержащий использование my-abc ), который я (Emacs) просматриваю?». Это не (B) «каков текущий буфер сейчас?». Если вы только что нажали C-x C-e, скажем foo.el , в буфере, и если выражение, в котором вы нажали C-x c-e, содержало вызов функции с именем 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) в этом случае является не буфер, который определил макрос, а буфер, в котором находится код, вызвавший макрос.

Комментарии:

1. Отличное объяснение. Спасибо!