Emacs 24.4の新しいアドバイスシステムの実用的な利点


53

Emacs 24.4には新しいアドバイスシステムが付属しています。NEWSファイルは述べています:

**新しいパッケージnadvice.elは、より軽量なアドバイス機能を提供します。次のように階層化されます。

*** add-function/ remove-function。これは、プロセスフィルターや<foo>-functionフックなど、関数を実行する場所でコードを追加/削除するために使用できます。

*** advice-add/ advice-remove名前付き関数に関するアドバイスを追加/削除するには、よくdefadviceやる。

Q:この新しいパッケージの実際的な利点と意味は何ですか?

私は特に、次の点に対処する回答に興味があります。

  • (アドオンパッケージを書くのではなく)Emacsをカスタマイズするためにアドバイスだけを使用している場合、新しいシステムに切り替える必要がありますか?ある時点で古いシステムを置き換えますか?

  • 私が達成できない新しいシステムで正確にできdefadviceますか?

  • 「機能を実行する場所でコードを追加/削除」できることの重要性は何ですか?

回答:


57

新しいアドバイスシステムには、次の利点があります。

  • add-function:これは、単に欠点の一部ではなかったまったく新しい機能です。それは間のハイブリッドのようなものであるadd-hookdefadvice。将来的には、より多くの期待foo-function(VIA修飾変数add-function)未満foo-functions(VIA修飾add-hook)。この機能は、さまざまなパッケージ間でプロセスフィルターを「共有」する方法を尋ねるバグレポートによってトリガーされる、新しいアドバイスシステムを実装する主な動機でした。

  • 実装の簡素化:一度実装さadd-functionれると、advice-add100KBのadvice.elのほとんどすべての機能を提供する機能を実装するのに8KBしかかかりません。

  • 設計の単純さ:defadviceにはさまざまな概念がありますが、これらの概念は一般に正確に理解するのが困難であるか、まれにしか使用されません。たとえば、「有効化」と「有効化」のアドバイスの違い。または、「pre」および/または「compiled」の意味。の処理にはad-do-it、呼び出しではなく変数参照のように見えるという事実や、(setq ad-return-value ...)単に値を返すのではなく明示的にする必要があるという事実などの癖もあります。

  • Defadviceは、マクロ展開とコンパイルに関してさまざまな問題に悩まされています。アドバイスの本文は、「コード」(コンパイラーとマクロエクスパンダーが見る)として公開されるのではなく、「データ」として公開されます。そのため、マクロ展開は遅く発生し(のようなものを使用すると驚きが生じる可能性があります(eval-when-compile (require 'foo)))、字句スコープは正しく保持するのが困難です。

新しいシステムに切り替える必要があるかどうかについては、将来のある時点で古い欠点を取り除くつもりですが、この未来は比較的遠いと思います(最初に移動しlisp/obsolete、後で移動する必要があります)GNU ELPAへ)。


1
古いアドバイスシステムで提供されているのと同じ引数変更機能をnadvice.elに追加する計画はありますか?
アーロンミラー

いいえ、それはnadvice.elのコンテキストではほとんど意味をなしません。nadvice.elでは、アドバイス関数は単純で古い通常の関数です。ただし、:aroundアドバイス(:filter-argsまたは:filter-resultアドバイス)を使用して同じ効果を得ることができます。
ステファン

2
しかし、私はできません。関数に2つの引数をアドバイスし、2番目の引数のみを置き換えて、アドバイスされた関数が最初の引数の対話形式に従ってプロンプトを表示するようにしたいとします。新しいアドバイスは、アドバイスされた機能のインタラクティブなフォームを置き換えるいくつかの異なる方法を提供するようですが、それ以上のニュアンスを提供するものは見当たりません。
アーロンミラー

@AaronMiller:別のSXの質問にしてください。そうすれば、SXのコメントの人為的な制限なしに議論できます。
ステファン

で、完了emacs.stackexchange.com/q/19233/2162。フォローアップしていただきありがとうございます。(答えにあなたが言及したバグレポートを見てみたいのですが、Googleやメーリングリストのアーカイブ検索で見つけられませんでした。リンクしてくれませんか?)
アーロンミラー

9

アドバイスが通常の機能であることの明確な利点の1つは、で定義にアクセスできることですfind-function

現在、(新しいスタイルの)アドバイス機能のヘルプを表示すると、アドバイス機能のヘルプへのリンクが提供され、そこからソースへのリンクが提供されます(通常の機能ヘルプの場合)。

古いシステムはインラインでアドバイスdocstringを提供しましたが、コードを見る方法はありませんでした(通常はに頼っていましたrgrep)。

(個人的には、インラインdocstringを使用するのが好きなので、ヘルプを表示するための古いアプローチと新しいアプローチのブレンドを見たいと思いますが、それは可能性があると確信しています。)


2
はい、新しいアドバイスシステムで既存のdoc文字列に追加できないのは残念ですdefadviceこのEmacsバグレポートを参照してください。これは欠点です。
ドリュー

8

ファイルヘッダーから:

;;; Commentary:

;; This package lets you add behavior (which we call "piece of advice") to
;; existing functions, like the old `advice.el' package, but with much fewer
;; bells and whistles.

私がそれを読んだとき、主な目標は、古いアドバイスシステムよりもシンプルであることであり、より多くの機能を持たせることではありません。ドキュメントを読むと、の機能のadvice-addサブセットが含まれているように見えますが、プロセスフィルターなどの非伝統的な機能に助言するための素晴らしい機能が含まれているようです(おそらくで可能だったが、どうすればいいかわかりません)。defadviceadd-functiondefadvice

私の知る限り、defadvice公式には廃止されていないので、今のところ使用し続けてください(そして、パッケージの作成者であれば、24.4がより広く採用されるまで使用し続けるでしょう)。ただし、Emacsの作成者は最終的に新しいシステムに完全に移行したいように聞こえます。



はい。新しいものは違います。そして、はい、そこには多くの用途がdefadviceあります(そして、これからもあります)。
ドリュー

0

私がここで言及したことはありませんが、他の回答で言及されいる「新しい」アドバイスシステムのよりシンプルなアプローチ(より良いモジュール性と「接着剤」)によるものです、これは次のとおりです。追加、結合、削除、並べ替えなど、nadviceのアドバイスははるかに簡単です。

nadviceはこれを容易にするために少し助けが必要ですが、対話的に、動的に行うことさえ可能です。私はこの方法でnadviceを他に使用すること(アドバイスのインタラクティブな構成)を知りませんが、そのようなアプリケーションが少なくとも1つあります。Isearch +でそれを利用して、検索中に任意のIsearchフィルター述語(フィルター)の組み合わせを追加および削除できるようにします。

IOW、検索パターンを段階的に変更するのと同じように、複数のフィルターを使用してその場で検索を絞り込むことができます。

Isearchフィルタリングはvariableを使用して行われますisearch-filter-predicate。これは、かなり以前から利用可能です。しかし、Isearchフィルターはあまり定義されていません。通常、これらは静的であり、特定のコンテキスト(Wdiredなど)に対して事前定義されています。少なくともインタラクティブにユーザーが定義して使用することは、それほど簡単ではありません。

変数は1つしかないisearch-filter-predicateため、フィルタリングの変更は、単一のフィルター述語の変更を意味します。これは関数の構成、述語の結合、検索の絞り込み、拡張、またはその他の変更に相当します。

しかし、それはまさにnadviceが得意なことです。要するに、nadviceは機能を組み合わせるのに非常に便利であるため、検索フィルタリングをインタラクティブに改良するのが簡単になります。(これについての詳細は、動的Isearchフィルタリングを参照してください。)

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.