Каковы новые правила для области видимости переменных в Emacs 24? - PullRequest
18 голосов
/ 05 октября 2011

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

Ответы [ 2 ]

21 голосов
/ 05 октября 2011

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

Ch 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

3 голосов
/ 16 августа 2013

Допустим, что некоторый код оценивается шаг за шагом в 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 верно ли для этого буфера?». Если да, Emacs оценивает my-abc, используя лексическую область, в противном случае, используя динамическую область.

Некоторое обновление: также, когда код цитируется как данные и затем передается в функцию eval, ответ на (A) не будет буфером. Тем не менее, eval создает воображаемый буфер для размещения кода и устанавливает локальное значение буфера lexical-binding для этого буфера во второй аргумент, переданный eval. Ответом на (A) является , а не буфер, содержащий вызов eval. Это мнимый буфер.

Для макросов Lisp, когда выполняется какой-то макрорасширенный код, это выглядит так, как будто расширенный код записывается в буфер, содержащий код, который вызвал макрос. Поэтому ответом на (A) в этом случае является не буфер, который определил макрос, но буфер, в котором находится код, который вызвал макрос.

...