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))
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.