Previous: Advice combinators, Up: Advising Functions [Contents][Index]
A lot of code uses the old defadvice
mechanism, which is largely made
obsolete by the new advice-add
, whose implementation and semantics is
significantly simpler.
An old advice such as:
(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))))
could be translated in the new advice mechanism into a plain function:
(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))))
Obviously, this does not actually modify previous-line
. For that the
old advice needed:
(ad-activate 'previous-line)
whereas the new advice mechanism needs:
(advice-add 'previous-line :before #'previous-line--next-line-at-end)
Note that ad-activate
had a global effect: it activated all pieces of
advice enabled for that specified function. If you wanted to only activate or
deactivate a particular advice, you needed to enable or disable
that advice with ad-enable-advice
and ad-disable-advice
.
The new mechanism does away with this distinction.
An around advice such as:
(defadvice foo (around foo-around) "Ignore case in `foo'." (let ((case-fold-search t)) ad-do-it)) (ad-activate 'foo)
could translate into:
(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)
Regarding the advice’s class, note that the new :before
is not
quite equivalent to the old before
, because in the old advice you could
modify the function’s arguments (e.g., with ad-set-arg
), and that would
affect the argument values seen by the original function, whereas in the new
:before
, modifying an argument via setq
in the advice has no
effect on the arguments seen by the original function.
When porting a before
advice which relied on this behavior, you’ll need
to turn it into a new :around
or :filter-args
advice instead.
Similarly an old after
advice could modify the returned value by
changing ad-return-value
, whereas a new :after
advice cannot, so
when porting such an old after
advice, you’ll need to turn it into a new
:around
or :filter-return
advice instead.
Previous: Advice combinators, Up: Advising Functions [Contents][Index]