O recurso de aconselhamento permite modificar o comportamento de uma função globalmente. Uma definição de conselho pode fazer chamadas para a função original.
(defadvice foo
(around foo-bar activate compile)
"Always set `qux' to t when running `foo'."
(let ((qux t))
ad-do-it))
O cl
pacote fornece a flet
macro para substituir uma função localmente.
(defun foo ()
"global")
(flet ((foo ()
"local"))
(some-code-that-calls-foo))
Isso não permite uma referência à foo
função original . E se a substituição local precisar chamar a função original?
(defun foo ()
"global")
(flet ((foo ()
(concat (foo) "+local")))
;; this will cause an infinite loop when (foo) is called
(some-code-that-calls-foo))
Essa abordagem direta não funciona, por um bom motivo: (foo)
é uma chamada recursiva à definição local.
Qual é a maneira não complicada de substituir localmente uma função, que permite chamar a função original a partir do código de substituição?
Aplicação: aplicar um patch em algum código existente, em um caso em foo
que não deve ser recuperado globalmente, mas o código precisa chamar o original. Aqui está o exemplo mais recente que eu queria:
(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)))
Eu queria voltar a ligar buffer-file-name
localmente e ligar para o original buffer-file-name
. Ok, neste caso específico, há uma solução alternativa, que é usar a buffer-file-name
variável. Mas o ponto da minha pergunta aqui é a técnica geral. Como posso vincular uma função (aqui buffer-file-name
) localmente, mas chamar a definição global da minha redefinição?
Isso é para o meu .emacs
, que continuo trabalhando no Emacs 19.34, para que soluções que exijam o Emacs 24.4 estejam disponíveis. No entanto, prefiro soluções que lidem com a ligação lexical de maneira limpa - mas a correção de macacos é inerentemente relacionada à ligação dinâmica.
cl-letf
está disponível em emacs 24.3 e antes, mas aqui é um relacionados Q & A: emacs.stackexchange.com/a/16495/221