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を変更することによりリターン値を変更できますが、新しい:afterは変更できないので、そのようなafterを移行するときは、かわりにそれらを新しいアドバイス:aroundか:filter-returnに変更する必要があるでしょう。