このマクロは、place に格納された関数にアドバイス function を追加する便利な方法です(一般化変数 を参照)。
where は、function が既存の関数とどのように組み合わされるか(例えば、function を元の関数の前と後のどちらで呼び出すか)を決定します。2つの関数を組み合わせるための利用可能な方法の一覧については、アドバイスの組み合わせ方を参照してください。
変数(通常、名前は -function で終わります)を変更する際、function をグローバルに使用するか、あるいは現在のバッファ内でのみ使用するかを選択できます。place が単なるシンボルである場合、function は place のグローバル値に加算されます。一方、place が
(local symbol)
という形式であり、symbol が変数名を返す式である場合、function は現在のバッファ内でのみ加算されます。最後に、字句変数を変更したい場合は、(var variable) を使用する必要があります。
add-function で追加される各関数には、プロパティの関連付けリスト props を添えることができます。現在、それらのプロパティのうち特別な意味を持つのは、以下の2つのみです:
nameこれによりアドバイスに名前が付与され、remove-function
はそれを用いてどの関数を削除すべきかを特定できます。通常、function
が無名関数である場合に使用されます。
depthこれは、複数のアドバイスが存在する場合に、それらをどのように順序付けるかを指定します。デフォルトでは、深度は0です。深度100はこのアドバイスを可能な限り深い位置に配置することを示し、一方で深度−100は最も外側に配置することを示します。2つのアドバイスが同じ深度を指定している場合、最後に追加された方が最外層となります。
:before
アドバイスにおいて、最外層であるということは、このアドバイスが他のどのアドバイスよりも先に実行されることを意味し、一方で最内層であるということは、元の関数の直前に実行され、元の関数との間に他のアドバイスが一切介在しないことを意味します。同様に、:after
アドバイスにおいても、最内層であることは元の関数の直後に実行され、その間に他のアドバイスが一切介在しないことを意味し、一方で最外層であることは、他のすべてのアドバイスの後、最後に実行されることを意味します。最内層の
:override
アドバイスは元の関数のみを上書きし、他のアドバイスはそれに適用されますが、最外層の :override アドバイスは元の関数だけでなく、それに適用される他のすべてのアドバイスをも上書きします。
function
がインタラクティブでない場合、合成関数は元の関数のインタラクティブ仕様(もしあれば)を継承します。そうでない場合、合成関数はインタラクティブとなり、function のインタラクティブ仕様を使用します。ただし、1点例外があります。function のインタラクティブ仕様が関数(すなわち、式や文字列ではなく、lambda 式または fbound
シンボル)である場合、合成関数のインタラクティブ仕様は、元の関数のインタラクティブ仕様を唯一の引数とするその関数の呼び出しとなります。引数として受け取った仕様を解釈するには、advice-eval-interactive-spec を使用してください。
注:function のインタラクティブ仕様は結合関数に適用されるため、function
ではなく結合関数の呼び出し規約に従う必要があります。多くの場合、両者は同一であるため違いはありませんが、:around、:filter-args、および :filter-return においては違いが生じます。これらの関数では、function が place
に格納されている元の関数とは異なる引数を受け取るためです。
このマクロは、placeに格納されている関数からfunctionを削除します。これは、functionがadd-functionを用いてplaceに追加されている場合にのみ動作します。
function は、ラムダ式でも動作するように、equal を用いて place
に追加された関数と比較されます。さらに、place に追加された関数の name プロパティとも比較されますが、こちらは equal
を用いてラムダ式を比較するよりも信頼性が高い場合があります。
advice が既に function-def
に含まれている場合は、nil 以外を返してください。前述の remove-function と同様に、advice
は実際の関数である代わりに、アドバイスの name である場合もあります。
function-defに追加された各アドバイスに対して、関数fを呼び出します。fには、アドバイス関数とそのプロパティという2つの引数が渡されます。
このような仕様を持つインタラクティブなspecを、関数へのインタラクティブな呼び出しと同様に評価し、構築された対応する引数リストを返します。例えば、(advice-eval-interactive-spec
"r\nP")は、領域の境界と現在のプレフィックス引数を含む3つの要素からなるリストを返します。
例えば、C-x m (compose-mail)
コマンドを ‘From:’
ヘッダーのプロンプトにしたい場合は、次のように記述できます。
(defun my-compose-mail-advice (&rest _)
"Read From: address interactively."
(interactive
(lambda (spec)
(let* ((user-mail-address
(completing-read "From: "
'("one.address@example.net"
"alternative.address@example.net")))
(from (message-make-from user-full-name
user-mail-address))
(spec (advice-eval-interactive-spec spec)))
;; Put the From header into the OTHER-HEADERS argument.
(push (cons 'From from) (nth 2 spec))
spec)))
;; This body is not used.
nil)
(advice-add 'compose-mail :interactive-only #'my-compose-mail-advice)