私の設定にはアドバイスがたくさんあり、新しい光沢のあるミニマリストのnadvice.elパッケージについて聞いています。
私はマニュアルを検索し、ソースを読みましたが、私は率直に認めます。
ここの誰かがガイドを教えてくれたり、古いスタイルのアドバイスを移植する方法を教えてもらえますか?
私の設定にはアドバイスがたくさんあり、新しい光沢のあるミニマリストのnadvice.elパッケージについて聞いています。
私はマニュアルを検索し、ソースを読みましたが、私は率直に認めます。
ここの誰かがガイドを教えてくれたり、古いスタイルのアドバイスを移植する方法を教えてもらえますか?
回答:
必要なすべての情報が含まれC-h f add-functionており、その中にあるメカニズムを説明していadvice-addます。
基本的に、新しいアドバイスシステムC-h f add-functionは、WHERE
引数の選択に応じて、関数の現在の定義をの表に記載されている関数で置き換えるように機能し
ます。
:aroundオプション付きの例最も一般的なケースは:aroundオプションであるため、その例を示します。(おそらくWHERE、可能であれば専用のパラメーターを使用することをお勧めしますが、同等の:around機能で他のものをすべて置き換えることができ
ます)。
ちょうど例として、呼び出されるたびfind-file
にprintその使用法をデバッグし、引数リストにしたいとしましょう。あなたは書くことができます
(defun my-find-file-advice-print-arguments (old-function &rest arguments)
"Print the argument list every time the advised function is called."
(print arguments)
(apply old-function arguments))
(advice-add #'find-file :around #'my-find-file-advice-print-arguments)
この新しい実装では、アドバイスに必要なすべてのものが引数として渡されます。ad-get-args引数は通常の関数の引数としてアドバイス関数に渡されるため(WHEREそれが意味をなす引数の場合)、不要になり
ます。アドバイスが引数として関数と引数を取得するad-do-itため、不要になる:aroundため(ad-do-it)、次の形式に置き換えられます。
(apply old-function arguments)
または引数に名前を付けたとき
(funcall old-function first-arg second-arg)
魔法のフォームが含まれていないので、よりクリーンです。引数を変更するには、変更した値をに渡すだけOLD-FUNCTIONです。
WHERE値のdocstringにadd-functionは、すべてのアドバイスプレース(または「コンビネーター」)とそれらの同等物のテーブルが含まれ、アドバイスされた機能とlambda同等の動作に関して機能を説明します。
`:before' (lambda (&rest r) (apply FUNCTION r) (apply OLDFUN r))
`:after' (lambda (&rest r) (prog1 (apply OLDFUN r) (apply FUNCTION r)))
`:around' (lambda (&rest r) (apply FUNCTION OLDFUN r))
`:override' (lambda (&rest r) (apply FUNCTION r))
`:before-while' (lambda (&rest r) (and (apply FUNCTION r) (apply OLDFUN r)))
`:before-until' (lambda (&rest r) (or (apply FUNCTION r) (apply OLDFUN r)))
`:after-while' (lambda (&rest r) (and (apply OLDFUN r) (apply FUNCTION r)))
`:after-until' (lambda (&rest r) (or (apply OLDFUN r) (apply FUNCTION r)))
`:filter-args' (lambda (&rest r) (apply OLDFUN (funcall FUNCTION r)))
`:filter-return'(lambda (&rest r) (funcall FUNCTION (apply OLDFUN r)))
(cited from `C-h f add-function')
ここで、FUNCTIONはアドバイス関数であり、OLDFUNはアドバイスが追加される関数です。一度にすべてを理解しようとするのではなく、WHERE適切に聞こえる記号を選択して、その記号を理解してください。
または、単に使用します:around。すべてに特化したWHEREs を使用することの唯一の利点
は、アドバイスのdocstringを読む前に:around調べることでもう少し情報が得られることですC-h f ADVISED-FUNCTION。アドバイスを含むコードを公開する予定がない限り、おそらく重要ではありません。
多くの利点を提供するため、名前付き関数をアドバイスとして使用することをお勧めします(フックの名前付き関数の使用にも適用されるものもあります)。
次のように表示されC-h f find-fileます
:around advice: `my-find-file-advice-print-arguments'
アドバイス関数の定義へのリンク。通常は、関数が定義されたファイルへのリンクが含まれています。アドバイスがlambdaフォーム内で直接フォームとして定義されていた場合、advice-add
docstringはインラインで表示され(長いdocstringの混乱?)、どこで定義されたかを示すものはありません。
アドバイスを削除するには
(advice-remove #'find-file #'my-find-file-advice-print-arguments)
advice-add古いバージョンを再実行したり危険にさらしたりせずに、アドバイスの定義を更新できます
(advice-add変更された状態で実行
lambdaすると、古いアドバイスの更新としてではなく、新しいアドバイスとして認識されます)。
補足説明この#'function表記法は'function、バイトコンパイラーがシンボルを関数名として識別し、欠落している関数(タイプミスなど)を識別するのに役立つことを除いて、基本的にに相当し
ます。
advice-addボーダーケースだと思います。個人的には、' ↔ #'区別は主に関数名のタイプミスを識別するのに役立つと考えているため、ここではおそらく、アドバイスが追加されるまでに関数が定義されることを期待するかどうかに依存します。
add-function)。ドキュメントがそれをより明確にしたいです。私はそれのためにパッチを作成することを期待するかもしれません。
C-h f find-fileではなく、で表示されC-xますか?
M-x report-emacs-bug。一部の開発者は、文書化よりも開発を好む場合があります。;-) Emacs自体を文書化することが重要です。