Mit der Hinweisfunktion können Sie das Verhalten einer Funktion global ändern. Eine Hinweisdefinition kann die ursprüngliche Funktion aufrufen.
(defadvice foo
(around foo-bar activate compile)
"Always set `qux' to t when running `foo'."
(let ((qux t))
ad-do-it))
Das clPaket enthält das fletMakro zum lokalen Überschreiben einer Funktion.
(defun foo ()
"global")
(flet ((foo ()
"local"))
(some-code-that-calls-foo))
Das erlaubt keinen Verweis auf die ursprüngliche fooFunktion. Was ist, wenn die lokale Überschreibung die ursprüngliche Funktion aufrufen muss?
(defun foo ()
"global")
(flet ((foo ()
(concat (foo) "+local")))
;; this will cause an infinite loop when (foo) is called
(some-code-that-calls-foo))
Dieser einfache Ansatz funktioniert aus gutem Grund nicht: Er (foo)ist ein rekursiver Aufruf der lokalen Definition.
Was ist eine nicht umständliche Methode zum lokalen Überschreiben einer Funktion, mit der die ursprüngliche Funktion aus dem Überschreibungscode aufgerufen werden kann?
Anwendung: Affen-Patching eines vorhandenen Codes, in einem Fall, in dem foonicht global zurückgebunden werden sollte, der Code jedoch das Original aufrufen muss. Hier ist das neueste Beispiel, das ich wollte:
(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)))
Ich wollte buffer-file-namelokal neu binden und das Original aufrufen buffer-file-name. Ok, in diesem speziellen Fall gibt es eine Problemumgehung, bei der die buffer-file-nameVariable verwendet wird. Aber der Punkt meiner Frage hier ist die allgemeine Technik. Wie kann ich eine Funktion (hier buffer-file-name) lokal binden, aber die globale Definition aus meiner Neudefinition aufrufen?
Dies ist für meine .emacs, die ich weiterhin in Emacs 19.34 arbeite, sodass Lösungen, die Emacs 24.4 erfordern, nicht verfügbar sind. Ich bevorzuge zwar Lösungen, die mit lexikalischer Bindung sauber umgehen - aber beim Affen-Patching geht es von Natur aus um dynamische Bindung.
cl-letfin Emacs 24.3 und früher verfügbar ist, aber hier ist eine verwandte Frage