アドバイス機能により、関数の動作をグローバルに変更できます。アドバイス定義は、元の関数を呼び出すことができます。
(defadvice foo
(around foo-bar activate compile)
"Always set `qux' to t when running `foo'."
(let ((qux t))
ad-do-it))
clパッケージは提供しflet、ローカルの機能を無効にするマクロを。
(defun foo ()
"global")
(flet ((foo ()
"local"))
(some-code-that-calls-foo))
それは元のfoo関数への参照を許可しません。ローカルのオーバーライドで元の関数を呼び出す必要がある場合はどうなりますか?
(defun foo ()
"global")
(flet ((foo ()
(concat (foo) "+local")))
;; this will cause an infinite loop when (foo) is called
(some-code-that-calls-foo))
この単純なアプローチは、適切な理由で機能しません(foo)。ローカル定義への再帰的な呼び出しです。
オーバーライドコードから元の関数を呼び出すことができる、関数をローカルでオーバーライドする面倒な方法は何ですか?
アプリケーション:fooグローバルにリバウンドされるべきではないが、コードがオリジナルを呼び出す必要がある場合に、いくつかの既存のコードをサルパッチングします。これが私が望んでいた最新の例です:
(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)))
buffer-file-nameローカルで再バインドし、元のを呼び出したかったbuffer-file-name。この特定のケースでは、buffer-file-name変数を使用するという回避策があります。しかし、ここで私の質問のポイントは、一般的な手法です。関数(ここbuffer-file-name)をローカルにバインドし、再定義からグローバル定義を呼び出すにはどうすればよいですか?
これは私用で、.emacsEmacs 19.34で作業を続けているため、Emacs 24.4を必要とするソリューションは廃止されました。私はレキシカルバインディングをきれいに処理するソリューションを好みますが、モンキーパッチングは本質的に動的バインディングについてです。
cl-letfのemacs 24.3と前に提供されていますが、ここでは、関連するQ&Aです:emacs.stackexchange.com/a/16495/221