The advice feature allows modifying the behavior of a function globally. An advice definition can make calls to the original function.
(defadvice foo (around foo-bar activate compile) "Always set `qux' to t when running `foo'." (let ((qux t)) ad-do-it)) The cl package provides the flet macro to override a function locally.
(defun foo () "global") (flet ((foo () "local")) (some-code-that-calls-foo)) That doesn't permit a reference to the original foo function. What if the local override needs to call the original function?
(defun foo () "global") (flet ((foo () (concat (foo) "+local"))) ;; this will cause an infinite loop when (foo) is called (some-code-that-calls-foo)) This straightforward approach doesn't work, for good reason: (foo) is a recursive call to the local definition.
What's a non-cumbersome way of locally overriding a function, that allows calling the original function from the override code?
Application: monkey-patching some existing code, in a case where foo should not be rebound globally, but the code needs to call the original. Here's the latest example I've been wanting:
(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))) I wanted to rebind buffer-file-name locally, and call the original buffer-file-name. Ok, in this specific case, there's a workaround, which is to use the buffer-file-name variable. But the point of my question here is the general technique. How can I bind a function (here buffer-file-name) locally but call the global definition from my redefinition?
This is for my .emacs, which I keep working in Emacs 19.34, so solutions that require Emacs 24.4 are out. I do prefer solutions that cope with lexical binding cleanly though — but monkey-patching is inherently about dynamic binding.
cl-letfis available in emacs 24.3 and before, but here is a related Q&A : emacs.stackexchange.com/a/16495/221