@c -*-texinfo-*-
@c This is part of the GNU Emacs Lisp Reference Manual.
-@c Copyright (C) 1998, 1999 Free Software Foundation, Inc.
+@c Copyright (C) 1998, 1999 Free Software Foundation, Inc.
@c See the file elisp.texi for copying conditions.
@setfilename ../info/advising
@node Advising Functions, Debugging, Byte Compilation, Top
@cindex piece of advice
Each function can have multiple @dfn{pieces of advice}, separately
-defined. Each defined piece of advice can be enabled or disabled
-explicitly. The enabled pieces of advice for any given function
-actually take effect when you @dfn{activate} advice for that function, or when
-that function is subsequently defined or redefined.
+defined. Each defined piece of advice can be @dfn{enabled} or
+disabled explicitly. All the enabled pieces of advice for any given
+function actually take effect when you @dfn{activate} advice for that
+function, or when you define or redefine the function. Note that
+enabling a piece of advice and activating advice for a function
+are not the same thing.
@strong{Usage Note:} Advice is useful for altering the behavior of
existing calls to an existing function. If you want the new behavior
* Preactivation:: Preactivation is a way of speeding up the
loading of compiled advice.
* Argument Access in Advice:: How advice can access the function's arguments.
-* Subr Arguments:: Accessing arguments when advising a primitive.
+* Advising Primitives:: Accessing arguments when advising a primitive.
* Combined Definition:: How advice is implemented.
@end menu
The command @code{next-line} moves point down vertically one or more
lines; it is the standard binding of @kbd{C-n}. When used on the last
line of the buffer, this command inserts a newline to create a line to
-move to (if @code{next-line-add-newlines} is non-@code{nil}).
+move to if @code{next-line-add-newlines} is non-@code{nil} (its default
+is @code{nil}.)
Suppose you wanted to add a similar feature to @code{previous-line},
which would insert a new line at the beginning of the buffer for the
-command to move to. How could you do this?
+command to move to (when @code{next-line-add-newlines} is
+non-@code{nil}). How could you do this?
You could do it by redefining the whole function, but that is not
modular. The advice feature provides a cleaner alternative: you can
defining this piece of advice.
@cindex forward advice
-This flag has no effect if @var{function} itself is not defined yet (a
+This flag has no immediate effect if @var{function} itself is not defined yet (a
situation known as @dfn{forward advice}), because it is impossible to
activate an undefined function's advice. However, defining
@var{function} will automatically activate its advice.
searches when the original definition of @code{foo} is run.
@defvar ad-do-it
-This is not really a variable, but it is somewhat used like one
-in around-advice. It specifies the place to run the function's
-original definition and other ``earlier'' around-advice.
+This is not really a variable, rather a place-holder that looks like a
+variable. You use it in around-advice to specify the place to run the
+function's original definition and other ``earlier'' around-advice.
@end defvar
If the around-advice does not use @code{ad-do-it}, then it does not run
@cindex advice, activating
By default, advice does not take effect when you define it---only when
-you @dfn{activate} advice for the function that was advised. You can
-request the activation of advice for a function when you define the
-advice, by specifying the @code{activate} flag in the @code{defadvice}.
-But normally you activate the advice for a function by calling the
-function @code{ad-activate} or one of the other activation commands
-listed below.
+you @dfn{activate} advice for the function that was advised. However
+the advice will be automatically activated if the function is defined
+or redefined later. You can request the activation of advice for a
+function when you define the advice, by specifying the @code{activate}
+flag in the @code{defadvice}. But normally you activate the advice
+for a function by calling the function @code{ad-activate} or one of
+the other activation commands listed below.
Separating the activation of advice from the act of defining it permits
you to add several pieces of advice to one function efficiently, without
This command activates all the advice defined for @var{function}.
@end deffn
-To activate advice for a function whose advice is already active is not
-a no-op. It is a useful operation which puts into effect any changes in
-that function's advice since the previous activation of advice for that
-function.
+ Activating advice does nothing if @var{function}'s advice is already
+active. But if there is new advice, added since the previous time you
+activated advice for @var{function}, it activates the new advice.
@deffn Command ad-deactivate function
This command deactivates the advice for @var{function}.
@deffn Command ad-start-advice
Turn on automatic advice activation when a function is defined or
-redefined. If you turn on this mode, then advice takes effect
-immediately when defined.
+redefined. This is the default mode.
@end deffn
@deffn Command ad-stop-advice
This variable controls whether to compile the combined definition
that results from activating advice for a function.
-A value of @code{always} specifies to compile unconditionally
-A value of @code{nil} specifies never compile the advice.
+A value of @code{always} specifies to compile unconditionally.
+A value of @code{never} specifies never compile the advice.
A value of @code{maybe} specifies to compile if the byte-compiler is
already loaded. A value of @code{like-original} specifies to compile
-the advice if the the original definition of the advised function is
+the advice if the original definition of the advised function is
compiled or a built-in function.
This variable takes effect only if the @var{compile} argument of
These argument constructs are not really implemented as Lisp macros.
Instead they are implemented specially by the advice mechanism.
-@node Subr Arguments
-@section Definition of Subr Argument Lists
+@node Advising Primitives
+@section Advising Primitives
- When the advice facility constructs the combined definition, it needs
-to know the argument list of the original function. This is not always
-possible for primitive functions. When advice cannot determine the
-argument list, it uses @code{(&rest ad-subr-args)}, which always works
-but is inefficient because it constructs a list of the argument values.
-You can use @code{ad-define-subr-args} to declare the proper argument
-names for a primitive function:
+ Advising a primitive function (also called a ``subr'') is risky.
+Some primitive functions are used by the advice mechanism; advising
+them could cause an infinite recursion. Also, many primitive
+functions are called directly from C code. Calls to the primitive
+from Lisp code will take note of the advice, but calls from C code
+will ignore the advice.
+
+When the advice facility constructs the combined definition, it needs
+to know the argument list of the original function. This is not
+always possible for primitive functions. When advice cannot determine
+the argument list, it uses @code{(&rest ad-subr-args)}, which always
+works but is inefficient because it constructs a list of the argument
+values. You can use @code{ad-define-subr-args} to declare the proper
+argument names for a primitive function:
@defun ad-define-subr-args function arglist
This function specifies that @var{arglist} should be used as the
@node Combined Definition
@section The Combined Definition
- Suppose that a function has @var{n} pieces of before-advice, @var{m}
-pieces of around-advice and @var{k} pieces of after-advice. Assuming no
-piece of advice is protected, the combined definition produced to
-implement the advice for a function looks like this:
+ Suppose that a function has @var{n} pieces of before-advice
+(numbered from 0 through @var{n}@minus{}1), @var{m} pieces of
+around-advice and @var{k} pieces of after-advice. Assuming no piece
+of advice is protected, the combined definition produced to implement
+the advice for a function looks like this:
@example
(lambda @var{arglist}
(let (ad-return-value)
@r{before-0-body-form}...
....
- @r{before-@var{n}-1-body-form}...
+ @r{before-@var{n}@minus{}1-body-form}...
@r{around-0-body-form}...
@r{around-1-body-form}...
....
- @r{around-@var{m}-1-body-form}...
+ @r{around-@var{m}@minus{}1-body-form}...
(setq ad-return-value
@r{apply original definition to @var{arglist}})
- @r{other-around-@var{m}-1-body-form}...
+ @r{end-of-around-@var{m}@minus{}1-body-form}...
....
- @r{other-around-1-body-form}...
- @r{other-around-0-body-form}...
+ @r{end-of-around-1-body-form}...
+ @r{end-of-around-0-body-form}...
@r{after-0-body-form}...
....
- @r{after-@var{k}-1-body-form}...
+ @r{after-@var{k}@minus{}1-body-form}...
ad-return-value))
@end example
The interactive form is present if the original function or some piece
of advice specifies one. When an interactive primitive function is
-advised, a special method is used: to call the primitive with
+advised, advice uses a special method: it calls the primitive with
@code{call-interactively} so that it will read its own arguments.
In this case, the advice cannot access the arguments.
according to their specified order. The forms of around-advice @var{l}
are included in one of the forms of around-advice @var{l} @minus{} 1.
-The innermost part of the around advice onion is
+The innermost part of the around advice onion is
@display
apply original definition to @var{arglist}
executed even if some previous piece of advice had an error or a
non-local exit. If any around-advice is protected, then the whole
around-advice onion is protected as a result.
+
+@ignore
+ arch-tag: 80c135c2-f1c3-4f8d-aa85-f8d8770d307f
+@end ignore