アドバイス機能により、関数の動作をグローバルに変更できます。アドバイス定義は、元の関数を呼び出すことができます。
(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
)をローカルにバインドし、再定義からグローバル定義を呼び出すにはどうすればよいですか?
これは私用で、.emacs
Emacs 19.34で作業を続けているため、Emacs 24.4を必要とするソリューションは廃止されました。私はレキシカルバインディングをきれいに処理するソリューションを好みますが、モンキーパッチングは本質的に動的バインディングについてです。
cl-letf
のemacs 24.3と前に提供されていますが、ここでは、関連するQ&Aです:emacs.stackexchange.com/a/16495/221