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に依存している場合は、関数のバインディングではなく、その変数のバインディングを使用することをお勧めします。letflet
編集:
もちろん、これらのアプローチでは、何が起こっているのかを理解するのが難しくなります。正確な状況によっては、sample関数を単純に再定義して、必要なことを実行する(または、my-sample提案したように、その場所で呼び出す関数を作成する)ことが望ましい場合があります。