Previous: Advice combinators, Up: Advising Functions [Contents][Index]
多くのコードは古いdefadvice
メカニズムを使用しており、これらの大半はadvice-add
によって陳腐化しました。advice-add
の実装とセマンティックは非常にシンプルです。
古いアドバイスは以下のようなものです:
(defadvice previous-line (before next-line-at-end (&optional arg try-vscroll)) "Insert an empty line when moving up from the top line." (if (and next-line-add-newlines (= arg 1) (save-excursion (beginning-of-line) (bobp))) (progn (beginning-of-line) (newline))))
新しいアドバイスメカニズムを使用すれば、これを通常の関数に変換できます:
(defun previous-line--next-line-at-end (&optional arg try-vscroll) "Insert an empty line when moving up from the top line." (if (and next-line-add-newlines (= arg 1) (save-excursion (beginning-of-line) (bobp))) (progn (beginning-of-line) (newline))))
これが実際のprevious-line
を変更しないことは明確です。古いアドバイスには以下が必要です:
(ad-activate 'previous-line)
一方、新しいアドバイスメカニズムでは以下が必要です:
(advice-add 'previous-line :before #'previous-line--next-line-at-end)
ad-activate
はグローバルな効果をもつことに注意してください。これは、指定された関数にたいして、アドバイスのすべての断片を有効にします。特定のアドバイスだけをアクティブ、または非アクティブにしたい場合、ad-enable-advice
、またはad-disable-advice
により、有効または無効にする必要があります。新しいメカニズムではこの区別はなくなりました。
以下のようなaroundのアドバイスがあるとします:
(defadvice foo (around foo-around) "Ignore case in `foo'." (let ((case-fold-search t)) ad-do-it)) (ad-activate 'foo)
これは以下のように変換できます:
(defun foo--foo-around (orig-fun &rest args) "Ignore case in `foo'." (let ((case-fold-search t)) (apply orig-fun args))) (advice-add 'foo :around #'foo--foo-around)
アドバイスのクラスについて、新たな:before
は、古いbefore
は完全に等価ではないことに注意してください。なぜなら古いアドバイス内では、(たとえばad-set-arg
を使って)その関数の引数を変更できそれは元の関数が参照する引数値に影響します。しかし新しい:before
は、setq
を通じてアドバイス内の引数をし、その変更は元の関数からの参照に影響しません。この振る舞いにもとづいてbefore
アドバイスを移行するときは、代わりにそれを新たなアドバイス:around
または:filter-args
に変更する必要があるでしょう。
同様に、古いafter
アドバイスは、ad-return-value
を変更することによりreturn値を変更できますが、新しい:after
は変更できないので、そのようなafter
を移行するときは、かわりにそれらを新しいアドバイス:around
または:filter-return
に変更する必要があるでしょう。