sds の答えは機能しますが、おそらくが実行されているbar
ときにのみアドバイスしsample
たい場合があるため、 のアドバイスをアクティブ化および非アクティブ化するには、サンプルにもアドバイスする必要がありますbar
。私のwith-temporary-advice
マクロはこれを容易にします:
(defmacro with-temporary-advice (function class name &rest body)
"Enable the specified advice, evaluate BODY, then disable the advice."
`(unwind-protect
(progn
(ad-enable-advice ,function ,class ,name)
(ad-activate ,function)
,@body)
(ad-disable-advice ,function ,class ,name)
(ad-activate ,function)))
(defadvice bar (around my-conditional-bar disable)
;; This advice disabled by default, and enabled dynamically.
(when condition
ad-do-it))
(defadvice sample (around my-sample-advice activate)
"Make execution of `bar' conditional when running `sample'."
(with-temporary-advice 'bar 'around 'my-conditional-bar
ad-do-it))
bar
の実行中に も他の方法で呼び出された場合、アドバイスはそれらの呼び出しにも適用されることに注意してsample
ください。その可能性がある場合は、それを考慮する必要があります。
または、必要に応じて を使用flet
して再定義bar
することをお勧めします。もちろん、これには最初の解決策と同じ注意事項があります。
(defadvice sample (around my-sample-advice activate)
"Make execution of `bar' conditional when running `sample'."
(if condition
ad-do-it
(flet ((bar () nil))
ad-do-it)))
これははるかに読みやすいですが、私が理解できない理由によりflet
、Emacs 24.3 の時点で、もはや支持されていません。その docstring はcl-flet
代わりに使用することを提案していますが、cl-flet
字句バインディングを使用しているため、実際には機能しません。私が知るflet
限り、実際にはなくなっていないように聞こえましたが、現在の推奨事項は代わりにアドバイスを使用することです.
また、 の内部で、望ましくない動作が変数bar
に依存している場合は、関数のバインディングではなく、その変数のバインディングを使用することをお勧めします。let
flet
編集:
もちろん、これらのアプローチでは、何が起こっているのかを理解するのが難しくなります。正確な状況によっては、sample
関数を単純に再定義して、必要なことを実行する(または、my-sample
提案したように、その場所で呼び出す関数を作成する)ことが望ましい場合があります。