summaryrefslogtreecommitdiff
path: root/devdocs/elisp/advising-named-functions.html
blob: fc6283d5f624c31538aa1f1216178f98beac187c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 <h4 class="subsection">Advising Named Functions</h4>  <p>A common use of advice is for named functions and macros. You could just use <code>add-function</code> as in: </p> <div class="example"> <pre class="example">(add-function :around (symbol-function '<var>fun</var>) #'his-tracing-function)
</pre>
</div> <p>But you should use <code>advice-add</code> and <code>advice-remove</code> for that instead. This separate set of functions to manipulate pieces of advice applied to named functions, offers the following extra features compared to <code>add-function</code>: they know how to deal with macros and autoloaded functions, they let <code>describe-function</code> preserve the original docstring as well as document the added advice, and they let you add and remove advice before a function is even defined. </p> <p><code>advice-add</code> can be useful for altering the behavior of existing calls to an existing function without having to redefine the whole function. However, it can be a source of bugs, since existing callers to the function may assume the old behavior, and work incorrectly when the behavior is changed by advice. Advice can also cause confusion in debugging, if the person doing the debugging does not notice or remember that the function has been modified by advice. </p> <p>For these reasons, advice should be reserved for the cases where you cannot modify a function’s behavior in any other way. If it is possible to do the same thing via a hook, that is preferable (see <a href="hooks">Hooks</a>). If you simply want to change what a particular key does, it may be better to write a new command, and remap the old command’s key bindings to the new one (see <a href="remapping-commands">Remapping Commands</a>). </p> <p>If you are writing code for release, for others to use, try to avoid including advice in it. If the function you want to advise has no hook to do the job, please talk with the Emacs developers about adding a suitable hook. Especially, Emacs’s own source files should not put advice on functions in Emacs. (There are currently a few exceptions to this convention, but we aim to correct them.) It is generally cleaner to create a new hook in <code>foo</code>, and make <code>bar</code> use the hook, than to have <code>bar</code> put advice in <code>foo</code>. </p> <p>Special forms (see <a href="special-forms">Special Forms</a>) cannot be advised, however macros can be advised, in much the same way as functions. Of course, this will not affect code that has already been macro-expanded, so you need to make sure the advice is installed before the macro is expanded. </p> <p>It is possible to advise a primitive (see <a href="what-is-a-function">What Is a Function</a>), but one should typically <em>not</em> do so, for two reasons. Firstly, some primitives are used by the advice mechanism, and advising them could cause an infinite recursion. Secondly, many primitives are called directly from C, and such calls ignore advice; hence, one ends up in a confusing situation where some calls (occurring from Lisp code) obey the advice and other calls (from C code) do not. </p> <dl> <dt id="define-advice">Macro: <strong>define-advice</strong> <em>symbol (where lambda-list &amp;optional name depth) &amp;rest body</em>
</dt> <dd><p>This macro defines a piece of advice and adds it to the function named <var>symbol</var>. The advice is an anonymous function if <var>name</var> is <code>nil</code> or a function named <code>symbol@name</code>. See <code>advice-add</code> for explanation of other arguments. </p></dd>
</dl> <dl> <dt id="advice-add">Function: <strong>advice-add</strong> <em>symbol where function &amp;optional props</em>
</dt> <dd><p>Add the advice <var>function</var> to the named function <var>symbol</var>. <var>where</var> and <var>props</var> have the same meaning as for <code>add-function</code> (see <a href="core-advising-primitives">Core Advising Primitives</a>). </p></dd>
</dl> <dl> <dt id="advice-remove">Function: <strong>advice-remove</strong> <em>symbol function</em>
</dt> <dd><p>Remove the advice <var>function</var> from the named function <var>symbol</var>. <var>function</var> can also be the <code>name</code> of a piece of advice. </p></dd>
</dl> <dl> <dt id="advice-member-p">Function: <strong>advice-member-p</strong> <em>function symbol</em>
</dt> <dd><p>Return non-<code>nil</code> if the advice <var>function</var> is already in the named function <var>symbol</var>. <var>function</var> can also be the <code>name</code> of a piece of advice. </p></dd>
</dl> <dl> <dt id="advice-mapc">Function: <strong>advice-mapc</strong> <em>function symbol</em>
</dt> <dd><p>Call <var>function</var> for every piece of advice that was added to the named function <var>symbol</var>. <var>function</var> is called with two arguments: the advice function and its properties. </p></dd>
</dl><div class="_attribution">
  <p class="_attribution-p">
    Copyright &copy; 1990-1996, 1998-2022 Free Software Foundation, Inc. <br>Licensed under the GNU GPL license.<br>
    <a href="https://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Named-Functions.html" class="_attribution-link">https://www.gnu.org/software/emacs/manual/html_node/elisp/Advising-Named-Functions.html</a>
  </p>
</div>