La función de asesoramiento permite modificar el comportamiento de una función a nivel mundial. Una definición de consejo puede hacer llamadas a la función original.
(defadvice foo
(around foo-bar activate compile)
"Always set `qux' to t when running `foo'."
(let ((qux t))
ad-do-it))
El cl
paquete proporciona la flet
macro para anular una función localmente.
(defun foo ()
"global")
(flet ((foo ()
"local"))
(some-code-that-calls-foo))
Eso no permite una referencia a la foo
función original . ¿Qué pasa si la anulación local necesita llamar a la función original?
(defun foo ()
"global")
(flet ((foo ()
(concat (foo) "+local")))
;; this will cause an infinite loop when (foo) is called
(some-code-that-calls-foo))
Este enfoque directo no funciona, por una buena razón: (foo)
es una llamada recursiva a la definición local.
¿Cuál es una forma no engorrosa de anular localmente una función, que permite llamar a la función original desde el código de anulación?
Aplicación: parchear algunos códigos existentes, en un caso en el foo
que no se debe rebotar globalmente, pero el código debe llamar al original. Aquí está el último ejemplo que he estado esperando:
(defadvice TeX-master-file
(around TeX-master-file-indirect-buffer activate compile)
"Support indirect buffers."
(flet ((buffer-file-name (&optional buffer)
(<global buffer-file-name> (buffer-base-buffer buffer))))
ad-do-it)))
Quería volver a unir buffer-file-name
localmente y llamar al original buffer-file-name
. Ok, en este caso específico, hay una solución alternativa, que es usar la buffer-file-name
variable. Pero el punto de mi pregunta aquí es la técnica general. ¿Cómo puedo vincular una función (aquí buffer-file-name
) localmente pero llamar a la definición global desde mi redefinición?
Esto es para mi .emacs
, que sigo trabajando en Emacs 19.34, por lo que las soluciones que requieren Emacs 24.4 están fuera. Sin embargo, prefiero soluciones que hagan frente a la unión léxica limpiamente, pero el parcheado de mono es inherentemente una unión dinámica.
cl-letf
esté disponible en emacs 24.3 y anteriores, pero aquí hay un Q&A relacionado: emacs.stackexchange.com/a/16495/221