2012-01-25 17 views
7

Acabo de pasar siglos averiguando qué pasaba con mi código. Funcionó muy bien en las pruebas de unidades de ert, pero falló cuando lo ejecuté en un contexto más amplio. Aquí está un ejemplo de un código que funcionó:¿Por qué el código en with-temp-buffer se queja de la variable void cuando el buffer "primario" tiene una variable local del mismo nombre que he enlazado?

(defun func (my-var) 
    (with-temp-buffer 
    (message my-var))) 

(func "z") 

Esto imprime z como se esperaba. Ahora estaba escribiendo un modo principal que tenía algunas variables de buffer-local. Uno de estos fue my-var. Este código demuestra mi problema:

(make-local-variable 'my-var) 
(setq my-var "y") 

(defun func (my-var) 
    (with-temp-buffer 
    (message my-var))) 

(func "z") 

¿La salida? No hay ninguna, solamente este mensaje de error:

eval-buffer: Symbol's value as variable is void: my-var 

En este ejemplo, es fácil ver que la variable local al búfer interfiere de alguna manera con el ligado de forma dinámica mi-var. No fue tan fácil cuando tenía varias pantallas que valían la pena de código :-)

Así que mi pregunta es qué está pasando realmente aquí? Es obvio que el temp-buffer de alguna manera hereda una variable del "padre", pero ¿por qué tiene un valor nulo? Entendería si de alguna manera obtendría el valor "y", pero este comportamiento me parece un error.

PS. Estoy ejecutando el último Aquamacs

Respuesta

3

Un par de cosas.

Primero, su código no funciona como está. Debería probar esto en una nueva invocación de Emacs. Una vez que lo hace, verá que usted necesita para pasar make-local-variable un símbolo, así:

(make-local-variable 'my-var) 

Nota del `` `.

En segundo lugar, ha definido una variable de buffer local para tener el mismo nombre que el parámetro func, por lo que cualquier respuesta necesita distinguir entre los dos.

Por lo tanto, aquí está mi limpiado versión de su ejemplo:

(make-local-variable 'my-var) 
(setq my-var "y") 

(defun func (my-param) 
    (with-temp-buffer 
(message my-param))) 

(func "z") 

Y esto funciona muy bien.

Lo que me lleva a creer que el error que está viendo proviene de la llamada al make-local-variable sin la cita al frente de my-var.

Respuesta original proporciona a continuación, aunque no aborda el problema:


Mira la documentación para make-local-variable. La cadena de documentación es:

make-local-variable es una función interactiva incorporada en `fuente de C código '.

(VARIABLE hacer-local-variable)

en Hacer variable tiene un valor separado en el búfer. Otros almacenamientos intermedios continuarán compartiendo un valor predeterminado común.(El valor buffer-local de VARIABLE comienza como el mismo valor VARIABLE tenía anteriormente. Si VARIABLE se anuló, permanece vacío.) Devuelve VARIABLE.

La parte clave para usted es la última oración. If the variable was void, it remains void.

Esto significa que si aún no se ha definido globalmente, aún no está definido globalmente. En otras palabras, solo tiene un enlace en los búferes en los que se ha establecido explícitamente.

Si desea que tenga un valor global, utilice setq-default así:

(setq-default my-var "some-default-value") 
+0

Pero todavía no entiendo por qué es nula. Lo creo con: (make-local-variable my-var) y luego le asigno el valor "y": (setq my-var "y"). Así que para cuando llame a la función y la macro with-temp-buffer dentro del valor no debería ser nula. ¿Qué me estoy perdiendo? – auramo

+0

"En otras palabras, solo tiene un enlace en los almacenamientos intermedios en los que se ha establecido explícitamente". <- No lo configuré explícitamente en el temp-buffer creado dentro de la macro con-temp-buffer. El buffer de alguna manera heredó la variable pero no su valor. Además, no quiero crear una variable global si puedo evitar eso. Puedo vivir con esta característica muy bien, solo tengo que recordar nombrar las variables cuidadosamente. Solo me gustaría saber por qué sucede esto. – auramo

+0

En realidad, hay un par de cosas sucediendo aquí en su código, actualizaré mi respuesta. –

Cuestiones relacionadas