2011-10-04 10 views
18

Emacs 24 ahora tiene variables de ámbito léxico. También tiene variables de ámbito dinámico, por supuesto. Ahora que tiene ambas, estoy bastante confundido acerca de cuándo una variable tendrá qué tipo de alcance. Hay una variable lexical-binding que controla cuando el enlace léxico está habilitado, y creo que he leído algo sobre defvar que ahora declara una variable de ámbito dinámico, pero en general estoy bastante perdido. ¿Hay alguna buena explicación en alguna parte de las nuevas reglas de alcance de Emacs 24? O dicho de otra forma, cuando miro una variable en el código de Emacs Lisp escrita para Emacs 24, ¿cómo puedo saber qué ámbito está usando esa variable?¿Cuáles son las nuevas reglas para el alcance variable en Emacs 24?

+2

Si ha instalado Emacs 24, esta información está disponible en la información. Abra el nodo "Emacs Lisp" y presione 'i' para buscar el índice. –

+0

Tengo ambos 23 y 24 instalados, por lo que fue un poco confuso. Hubo entradas de "Elisp" y "Elisp (emacs-snapshot)". Ya lo veo. Además, a veces me olvido de que Emacs es uno de los proyectos con buena documentación, y probablemente no del tipo para fusionar las principales características nuevas sin la documentación adecuada. –

Respuesta

21

El manual es la fuente definitiva. Haga clic aquí:

Chig(elisp) Variable ScopingRET

había citado inicialmente el manual en esta respuesta, pero esa información (data de Emacs 24.0.90.1) estaba ligeramente fuera de fecha. Es mejor leer el manual desde dentro de Emacs para que la información sea correcta para la versión que está usando.

Si particular quiere leerlo en una página web, la versión actual es:
http://www.gnu.org/software/emacs/manual/html_node/elisp/Variable-Scoping.html

3

Digamos que algún código se está evaluando paso a paso en Emacs (ya sea porque usted acaba de hacer C-x C-e o porque se está cargando un archivo Emacs Lisp o porque se está ejecutando una función de un enlace, etc.), y que Emacs está a punto de evaluar my-abc dentro de ese código. Tal vez my-abc es una variable local en ese código o tal vez no está declarado o tal vez tiene algún valor global, etc. De todos modos, el paso actual es la evaluación de my-abc. En ese punto, Emacs verifica solo dos cosas para decidir si se evalúa my-abc utilizando el alcance léxico o no.

Lo primero que comprueba Emacs es "¿es my-abc una variable especial?". La respuesta a esa pregunta es sí si se ejecutó (defvar my-abc ...) o (defcustom my-abc ..) o cualquier otro punto en el pasado. Tal vez (defcustom my-abc ..) se ejecutó mientras cargaba algún otro archivo Emacs Lisp, o tal vez evaluó algún código que contenga (defvar my-abc ...) en el búfer de rayado, o tal vez no. Si la respuesta es sí por algún motivo, Emacs en este momento evaluará my-abc utilizando el alcance dinámico.

Si la respuesta es no, entonces Emacs verifica la segunda cosa, que es (A) "¿dónde está este código (que contiene el uso de my-abc) que I (Emacs) estoy atravesando?". Esto no es (B) "¿cuál es el búfer actual ahora?". Si acaba de presionar Cx Ce en un búfer, digamos foo.el, y si la expresión presionó Cx ce en contenía una llamada a una función llamada mah-hello que se define en mah-stuff.el, y si el cuerpo de la función mah-hello contenía una llamada a my-hello que se define en my-stuff.el, y si el cuerpo de la función my-hello contenía el uso de una variable llamada my-abc, cuando Emacs finalmente llega a ejecutar my-hello y luego está a punto de evaluar my-abc allí, en ese momento cuando Emacs hace la Pregunta A, responde my-stuff.el a sí mismo. No es el buffer foo.el que contiene la expresión inicial.

Entonces Emacs pregunta "¿es my-stuff.el un búfer de ámbito léxico, en otras palabras, es lexical-binding verdadero en ese búfer?".En caso afirmativo, Emacs evalúa my-abc utilizando el ámbito léxico, de lo contrario, utilizando el alcance dinámico.

Algunas actualizaciones: Además, cuando el código se cita como datos y luego pasa a la función eval, la respuesta a (A) no será un búfer. Aún así, es como si eval constituye un búfer imaginario para colocar el código, y establecer el valor de buffer local de lexical-binding para ese búfer en el segundo argumento pasado a eval. La respuesta a (A) es no el búfer que contiene la llamada `eval '. Es el buffer imaginario.

Para las macros Lisp, cuando se ejecuta un código macro expandido, es como si el código expandido se escribiera en el búfer que contiene el código que invoca la macro. Por lo tanto, la respuesta a (A) en este caso es no el búfer que definió la macro, pero el búfer donde reside el código que llamó a la macro.

+0

Gran explicación. ¡Gracias! – killdash9

Cuestiones relacionadas