Update Compilation and Advice chapters in Lisp manual.
* doc/lispref/advice.texi (Defining Advice): Clarify ad-unadvise. (Activation of Advice): Specifying the ACTIVATE flag in defadvice is not abnormal. (Advising Primitives): Node deleted; ad-define-subr-args has been removed. * doc/lispref/compile.texi (Speed of Byte-Code): Use float-time in example. (Compilation Functions): Note that the log uses Compilation mode. Don't discuss the contents of byte-code function object here. (Compilation Functions): De-document internal function byte-code. (Docs and Compilation): Minor clarifications. * doc/lispref/objects.texi (Byte-Code Type): Add xref to Byte-Code Function Objects. * lisp/emacs-lisp/advice.el: Update commentary to reflect deletion of ad-define-subr-args
This commit is contained in:
parent
d7c5e1622f
commit
25dec36509
9 changed files with 138 additions and 228 deletions
|
@ -180,13 +180,13 @@ xresources.texi cyd
|
|||
** Check the Lisp manual.
|
||||
|
||||
abbrevs.texi
|
||||
advice.texi
|
||||
advice.texi cyd
|
||||
anti.texi
|
||||
back.texi
|
||||
backups.texi
|
||||
buffers.texi
|
||||
commands.texi
|
||||
compile.texi
|
||||
compile.texi cyd
|
||||
control.texi cyd
|
||||
customize.texi cyd
|
||||
debugging.texi
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
2012-02-10 Chong Yidong <cyd@gnu.org>
|
||||
|
||||
* advice.texi (Defining Advice): Clarify ad-unadvise.
|
||||
(Activation of Advice): Specifying the ACTIVATE flag in defadvice
|
||||
is not abnormal.
|
||||
(Advising Primitives): Node deleted; ad-define-subr-args has been
|
||||
removed.
|
||||
|
||||
* compile.texi (Speed of Byte-Code): Use float-time in example.
|
||||
(Compilation Functions): Note that the log uses Compilation mode.
|
||||
Don't discuss the contents of byte-code function object here.
|
||||
(Compilation Functions): De-document internal function byte-code.
|
||||
(Docs and Compilation): Minor clarifications.
|
||||
|
||||
* objects.texi (Byte-Code Type): Add xref to Byte-Code Function
|
||||
Objects.
|
||||
|
||||
2012-02-10 Glenn Morris <rgm@gnu.org>
|
||||
|
||||
* text.texi (Checksum/Hash): Rename node from MD5 Checksum.
|
||||
|
|
|
@ -13,30 +13,35 @@ for a library to customize functions defined within Emacs---cleaner
|
|||
than redefining the whole function.
|
||||
|
||||
@cindex piece of advice
|
||||
Each function can have multiple @dfn{pieces of advice}, separately
|
||||
defined. Each defined piece of advice can be @dfn{enabled} or
|
||||
@dfn{disabled} explicitly. All the enabled pieces of advice for any given
|
||||
function actually take effect when you @dfn{activate} advice for that
|
||||
Each function can have multiple @dfn{pieces of advice}, each of
|
||||
which can be separately defined and then @dfn{enabled} or
|
||||
@dfn{disabled}. 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.
|
||||
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
|
||||
for new calls, or for key bindings, you should define a new function
|
||||
(or a new command) which uses the existing function.
|
||||
Advice is useful for altering the behavior of existing calls to an
|
||||
existing function. If you want the new behavior for new function
|
||||
calls or new key bindings, you should define a new function or
|
||||
command, and have it use the existing function as a subroutine.
|
||||
|
||||
@strong{Usage note:} Advising a function can cause confusion in
|
||||
debugging, since people who debug calls to the original function may
|
||||
not notice that it has been modified with advice. Therefore, if you
|
||||
have the possibility to change the code of that function (or ask
|
||||
someone to do so) to run a hook, please solve the problem that way.
|
||||
Advice should be reserved for the cases where you cannot get the
|
||||
function changed.
|
||||
Advising a function can cause confusion in debugging, since people
|
||||
who debug calls to the original function may not notice that it has
|
||||
been modified with advice. Therefore, if you have the possibility to
|
||||
change the code of that function to run a hook, please solve the
|
||||
problem that way. Advice should be reserved for the cases where you
|
||||
cannot get the function changed. In particular, Emacs' 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.
|
||||
|
||||
In particular, this means that a file in Emacs should not put advice
|
||||
on a function in Emacs. There are currently a few exceptions to this
|
||||
convention, but we aim to correct them.
|
||||
Unless you know what you are doing, do @emph{not} advise a primitive
|
||||
(@pxref{What Is a Function}). Some primitives are used by the advice
|
||||
mechanism; advising them could cause an infinite recursion. Also,
|
||||
many primitives 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.
|
||||
|
||||
@menu
|
||||
* Simple Advice:: A simple example to explain the basics of advice.
|
||||
|
@ -48,7 +53,6 @@ convention, but we aim to correct them.
|
|||
* 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.
|
||||
* Advising Primitives:: Accessing arguments when advising a primitive.
|
||||
* Combined Definition:: How advice is implemented.
|
||||
@end menu
|
||||
|
||||
|
@ -258,7 +262,7 @@ All subroutines used by the advice need to be available when the byte
|
|||
compiler expands the macro.
|
||||
|
||||
@deffn Command ad-unadvise function
|
||||
This command deletes the advice from @var{function}.
|
||||
This command deletes all pieces of advice from @var{function}.
|
||||
@end deffn
|
||||
|
||||
@deffn Command ad-unadvise-all
|
||||
|
@ -355,13 +359,13 @@ replaced with the new one.
|
|||
@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. However,
|
||||
the advice will be activated automatically if you define or redefine
|
||||
the function 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.
|
||||
you @dfn{activate} advice for the function. However, the advice will
|
||||
be activated automatically if you define or redefine the function
|
||||
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}; or you can activate the advice separately 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
|
||||
|
@ -680,39 +684,6 @@ will be 3, and @var{r} will be @code{(2 1 0)} inside the body of
|
|||
These argument constructs are not really implemented as Lisp macros.
|
||||
Instead they are implemented specially by the advice mechanism.
|
||||
|
||||
@node Advising Primitives
|
||||
@section Advising Primitives
|
||||
@cindex advising primitives
|
||||
|
||||
Advising a primitive function (@pxref{What Is a Function}) 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
|
||||
argument list for function @var{function}.
|
||||
@end defun
|
||||
|
||||
For example,
|
||||
|
||||
@example
|
||||
(ad-define-subr-args 'fset '(sym newdef))
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
specifies the argument list for the function @code{fset}.
|
||||
|
||||
@node Combined Definition
|
||||
@section The Combined Definition
|
||||
|
||||
|
|
|
@ -32,9 +32,6 @@ variable binding for @code{no-byte-compile} into it, like this:
|
|||
;; -*-no-byte-compile: t; -*-
|
||||
@end example
|
||||
|
||||
@xref{Compilation Errors}, for how to investigate errors occurring in
|
||||
byte compilation.
|
||||
|
||||
@menu
|
||||
* Speed of Byte-Code:: An example of speedup from byte compilation.
|
||||
* Compilation Functions:: Byte compilation functions.
|
||||
|
@ -56,18 +53,16 @@ Here is an example:
|
|||
@example
|
||||
@group
|
||||
(defun silly-loop (n)
|
||||
"Return time before and after N iterations of a loop."
|
||||
(let ((t1 (current-time-string)))
|
||||
(while (> (setq n (1- n))
|
||||
0))
|
||||
(list t1 (current-time-string))))
|
||||
"Return the time, in seconds, to run N iterations of a loop."
|
||||
(let ((t1 (float-time)))
|
||||
(while (> (setq n (1- n)) 0))
|
||||
(- (float-time) t1)))
|
||||
@result{} silly-loop
|
||||
@end group
|
||||
|
||||
@group
|
||||
(silly-loop 50000000)
|
||||
@result{} ("Wed Mar 11 21:10:19 2009"
|
||||
"Wed Mar 11 21:10:41 2009") ; @r{22 seconds}
|
||||
@result{} 10.235304117202759
|
||||
@end group
|
||||
|
||||
@group
|
||||
|
@ -77,18 +72,17 @@ Here is an example:
|
|||
|
||||
@group
|
||||
(silly-loop 50000000)
|
||||
@result{} ("Wed Mar 11 21:12:26 2009"
|
||||
"Wed Mar 11 21:12:32 2009") ; @r{6 seconds}
|
||||
@result{} 3.705854892730713
|
||||
@end group
|
||||
@end example
|
||||
|
||||
In this example, the interpreted code required 22 seconds to run,
|
||||
whereas the byte-compiled code required 6 seconds. These results are
|
||||
representative, but actual results will vary greatly.
|
||||
In this example, the interpreted code required 10 seconds to run,
|
||||
whereas the byte-compiled code required less than 4 seconds. These
|
||||
results are representative, but actual results may vary.
|
||||
|
||||
@node Compilation Functions
|
||||
@comment node-name, next, previous, up
|
||||
@section The Compilation Functions
|
||||
@section Byte-Compilation Functions
|
||||
@cindex compilation functions
|
||||
|
||||
You can byte-compile an individual function or macro definition with
|
||||
|
@ -96,43 +90,36 @@ the @code{byte-compile} function. You can compile a whole file with
|
|||
@code{byte-compile-file}, or several files with
|
||||
@code{byte-recompile-directory} or @code{batch-byte-compile}.
|
||||
|
||||
The byte compiler produces error messages and warnings about each file
|
||||
in a buffer called @samp{*Compile-Log*}. These report things in your
|
||||
program that suggest a problem but are not necessarily erroneous.
|
||||
Sometimes, the byte compiler produces warning and/or error messages
|
||||
(@pxref{Compiler Errors}, for details). These messages are recorded
|
||||
in a buffer called @samp{*Compile-Log*}, which uses Compilation mode.
|
||||
@xref{Compilation Mode,,,emacs, The GNU Emacs Manual}.
|
||||
|
||||
@cindex macro compilation
|
||||
Be careful when writing macro calls in files that you may someday
|
||||
byte-compile. Macro calls are expanded when they are compiled, so the
|
||||
macros must already be defined for proper compilation. For more
|
||||
details, see @ref{Compiling Macros}. If a program does not work the
|
||||
same way when compiled as it does when interpreted, erroneous macro
|
||||
definitions are one likely cause (@pxref{Problems with Macros}).
|
||||
Inline (@code{defsubst}) functions are less troublesome; if you
|
||||
Be careful when writing macro calls in files that you intend to
|
||||
byte-compile. Since macro calls are expanded when they are compiled,
|
||||
the macros need to be loaded into Emacs or the byte compiler will not
|
||||
do the right thing. The usual way to handle this is with
|
||||
@code{require} forms which specify the files containing the needed
|
||||
macro definitions (@pxref{Named Features}). Normally, the
|
||||
byte compiler does not evaluate the code that it is compiling, but it
|
||||
handles @code{require} forms specially, by loading the specified
|
||||
libraries. To avoid loading the macro definition files when someone
|
||||
@emph{runs} the compiled program, write @code{eval-when-compile}
|
||||
around the @code{require} calls (@pxref{Eval During Compile}). For
|
||||
more details, @xref{Compiling Macros}.
|
||||
|
||||
Inline (@code{defsubst}) functions are less troublesome; if you
|
||||
compile a call to such a function before its definition is known, the
|
||||
call will still work right, it will just run slower.
|
||||
|
||||
Normally, compiling a file does not evaluate the file's contents or
|
||||
load the file. But it does execute any @code{require} calls at top
|
||||
level in the file. One way to ensure that necessary macro definitions
|
||||
are available during compilation is to require the file that defines
|
||||
them (@pxref{Named Features}). To avoid loading the macro definition files
|
||||
when someone @emph{runs} the compiled program, write
|
||||
@code{eval-when-compile} around the @code{require} calls (@pxref{Eval
|
||||
During Compile}).
|
||||
|
||||
@defun byte-compile symbol
|
||||
This function byte-compiles the function definition of @var{symbol},
|
||||
replacing the previous definition with the compiled one. The function
|
||||
definition of @var{symbol} must be the actual code for the function;
|
||||
i.e., the compiler does not follow indirection to another symbol.
|
||||
@code{byte-compile} returns the new, compiled definition of
|
||||
@var{symbol}.
|
||||
|
||||
If @var{symbol}'s definition is a byte-code function object,
|
||||
@code{byte-compile} does nothing and returns @code{nil}. Lisp records
|
||||
only one function definition for any symbol, and if that is already
|
||||
compiled, non-compiled code is not available anywhere. So there is no
|
||||
way to ``compile the same definition again.''
|
||||
@code{byte-compile} does not handle function indirection. The return
|
||||
value is the byte-code function object which is the compiled
|
||||
definition of @var{symbol} (@pxref{Byte-Code Objects}).
|
||||
|
||||
@example
|
||||
@group
|
||||
|
@ -153,16 +140,15 @@ way to ``compile the same definition again.''
|
|||
@end group
|
||||
@end example
|
||||
|
||||
@noindent
|
||||
The result is a byte-code function object. The string it contains is
|
||||
the actual byte-code; each character in it is an instruction or an
|
||||
operand of an instruction. The vector contains all the constants,
|
||||
variable names and function names used by the function, except for
|
||||
certain primitives that are coded as special instructions.
|
||||
If @var{symbol}'s definition is a byte-code function object,
|
||||
@code{byte-compile} does nothing and returns @code{nil}. It does not
|
||||
``compile the symbol's definition again'', since the original
|
||||
(non-compiled) code has already been replaced in the symbol's function
|
||||
cell by the byte-compiled code.
|
||||
|
||||
If the argument to @code{byte-compile} is a @code{lambda} expression,
|
||||
it returns the corresponding compiled code, but does not store
|
||||
it anywhere.
|
||||
The argument to @code{byte-compile} can also be a @code{lambda}
|
||||
expression. In that case, the function returns the corresponding
|
||||
compiled code but does not store it anywhere.
|
||||
@end defun
|
||||
|
||||
@deffn Command compile-defun &optional arg
|
||||
|
@ -252,19 +238,6 @@ files that have an up-to-date @samp{.elc} file.
|
|||
@end example
|
||||
@end defun
|
||||
|
||||
@defun byte-code code-string data-vector max-stack
|
||||
@cindex byte-code interpreter
|
||||
This function actually interprets byte-code. A byte-compiled function
|
||||
is actually defined with a body that calls @code{byte-code}. Don't call
|
||||
this function yourself---only the byte compiler knows how to generate
|
||||
valid calls to this function.
|
||||
|
||||
In Emacs version 18, byte-code was always executed by way of a call to
|
||||
the function @code{byte-code}. Nowadays, byte-code is usually executed
|
||||
as part of a byte-code function object, and only rarely through an
|
||||
explicit call to @code{byte-code}.
|
||||
@end defun
|
||||
|
||||
@node Docs and Compilation
|
||||
@section Documentation Strings and Compilation
|
||||
@cindex dynamic loading of documentation
|
||||
|
@ -290,33 +263,11 @@ then further access to documentation strings in this file will
|
|||
probably give nonsense results.
|
||||
@end itemize
|
||||
|
||||
If your site installs Emacs following the usual procedures, these
|
||||
problems will never normally occur. Installing a new version uses a new
|
||||
directory with a different name; as long as the old version remains
|
||||
installed, its files will remain unmodified in the places where they are
|
||||
expected to be.
|
||||
|
||||
However, if you have built Emacs yourself and use it from the
|
||||
directory where you built it, you will experience this problem
|
||||
occasionally if you edit and recompile Lisp files. When it happens, you
|
||||
can cure the problem by reloading the file after recompiling it.
|
||||
|
||||
You can turn off this feature at compile time by setting
|
||||
@code{byte-compile-dynamic-docstrings} to @code{nil}; this is useful
|
||||
mainly if you expect to change the file, and you want Emacs processes
|
||||
that have already loaded it to keep working when the file changes.
|
||||
You can do this globally, or for one source file by specifying a
|
||||
file-local binding for the variable. One way to do that is by adding
|
||||
this string to the file's first line:
|
||||
|
||||
@example
|
||||
-*-byte-compile-dynamic-docstrings: nil;-*-
|
||||
@end example
|
||||
|
||||
@defvar byte-compile-dynamic-docstrings
|
||||
If this is non-@code{nil}, the byte compiler generates compiled files
|
||||
that are set up for dynamic loading of documentation strings.
|
||||
@end defvar
|
||||
@noindent
|
||||
These problems normally occur only if you build Emacs yourself and use
|
||||
it from the directory where you built it, and you happen to edit
|
||||
and/or recompile the Lisp source files. They can be easily cured by
|
||||
reloading each file after recompiling it.
|
||||
|
||||
@cindex @samp{#@@@var{count}}
|
||||
@cindex @samp{#$}
|
||||
|
@ -328,6 +279,23 @@ string.'' It is usually best not to use these constructs in Lisp source
|
|||
files, since they are not designed to be clear to humans reading the
|
||||
file.
|
||||
|
||||
You can disable the dynamic documentation string feature at compile
|
||||
time by setting @code{byte-compile-dynamic-docstrings} to @code{nil};
|
||||
this is useful mainly if you expect to change the file, and you want
|
||||
Emacs processes that have already loaded it to keep working when the
|
||||
file changes. You can do this globally, or for one source file by
|
||||
specifying a file-local binding for the variable. One way to do that
|
||||
is by adding this string to the file's first line:
|
||||
|
||||
@example
|
||||
-*-byte-compile-dynamic-docstrings: nil;-*-
|
||||
@end example
|
||||
|
||||
@defvar byte-compile-dynamic-docstrings
|
||||
If this is non-@code{nil}, the byte compiler generates compiled files
|
||||
that are set up for dynamic loading of documentation strings.
|
||||
@end defvar
|
||||
|
||||
@node Dynamic Loading
|
||||
@section Dynamic Loading of Individual Functions
|
||||
|
||||
|
@ -541,17 +509,16 @@ one you intend to suppress.
|
|||
@cindex byte-code function
|
||||
|
||||
Byte-compiled functions have a special data type: they are
|
||||
@dfn{byte-code function objects}.
|
||||
@dfn{byte-code function objects}. Whenever such an object appears as
|
||||
a function to be called, Emacs uses the byte-code interpreter to
|
||||
execute the byte-code.
|
||||
|
||||
Internally, a byte-code function object is much like a vector;
|
||||
however, the evaluator handles this data type specially when it appears
|
||||
as a function to be called. The printed representation for a byte-code
|
||||
function object is like that for a vector, with an additional @samp{#}
|
||||
before the opening @samp{[}.
|
||||
|
||||
A byte-code function object must have at least four elements; there is
|
||||
no maximum number, but only the first six elements have any normal use.
|
||||
They are:
|
||||
Internally, a byte-code function object is much like a vector; its
|
||||
elements can be accessed using @code{aref}. Its printed
|
||||
representation is like that for a vector, with an additional @samp{#}
|
||||
before the opening @samp{[}. It must have at least four elements;
|
||||
there is no maximum number, but only the first six elements have any
|
||||
normal use. They are:
|
||||
|
||||
@table @var
|
||||
@item arglist
|
||||
|
@ -588,7 +555,7 @@ representation. It is the definition of the command
|
|||
[arg 1 forward-sexp]
|
||||
2
|
||||
254435
|
||||
"p"]
|
||||
"^p"]
|
||||
@end example
|
||||
|
||||
The primitive way to create a byte-code object is with
|
||||
|
@ -604,10 +571,6 @@ function yourself, because if they are inconsistent, Emacs may crash
|
|||
when you call the function. Always leave it to the byte compiler to
|
||||
create these objects; it makes the elements consistent (we hope).
|
||||
|
||||
You can access the elements of a byte-code object using @code{aref};
|
||||
you can also use @code{vconcat} to create a vector with the same
|
||||
elements.
|
||||
|
||||
@node Disassembly
|
||||
@section Disassembled Byte-Code
|
||||
@cindex disassembled byte-code
|
||||
|
|
|
@ -548,7 +548,6 @@ Advising Emacs Lisp Functions
|
|||
* 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.
|
||||
* Advising Primitives:: Accessing arguments when advising a primitive.
|
||||
* Combined Definition:: How advice is implemented.
|
||||
|
||||
Debugging Lisp Programs
|
||||
|
|
|
@ -1323,11 +1323,11 @@ with the name of the subroutine.
|
|||
@node Byte-Code Type
|
||||
@subsection Byte-Code Function Type
|
||||
|
||||
The byte compiler produces @dfn{byte-code function objects}.
|
||||
Internally, a byte-code function object is much like a vector; however,
|
||||
the evaluator handles this data type specially when it appears as a
|
||||
function to be called. @xref{Byte Compilation}, for information about
|
||||
the byte compiler.
|
||||
@dfn{Byte-code function objects} are produced by byte-compiling Lisp
|
||||
code (@pxref{Byte Compilation}). Internally, a byte-code function
|
||||
object is much like a vector; however, the evaluator handles this data
|
||||
type specially when it appears in a function call. @xref{Byte-Code
|
||||
Objects}.
|
||||
|
||||
The printed representation and read syntax for a byte-code function
|
||||
object is like that for a vector, with an additional @samp{#} before the
|
||||
|
|
|
@ -568,7 +568,6 @@ Advising Emacs Lisp Functions
|
|||
* 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.
|
||||
* Advising Primitives:: Accessing arguments when advising a primitive.
|
||||
* Combined Definition:: How advice is implemented.
|
||||
|
||||
Debugging Lisp Programs
|
||||
|
|
|
@ -567,7 +567,6 @@ Advising Emacs Lisp Functions
|
|||
* 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.
|
||||
* Advising Primitives:: Accessing arguments when advising a primitive.
|
||||
* Combined Definition:: How advice is implemented.
|
||||
|
||||
Debugging Lisp Programs
|
||||
|
|
|
@ -348,10 +348,7 @@
|
|||
;; first argument list defined in the list of before/around/after advices.
|
||||
;; The values of <arglist> variables can be accessed/changed in the body of
|
||||
;; an advice by simply referring to them by their original name, however,
|
||||
;; more portable argument access macros are also provided (see below). For
|
||||
;; subrs/special-forms for which neither explicit argument list definitions
|
||||
;; are available, nor their documentation strings contain such definitions
|
||||
;; (as they do v19s), `(&rest ad-subr-args)' will be used.
|
||||
;; more portable argument access macros are also provided (see below).
|
||||
|
||||
;; <advised-docstring> is an optional, special documentation string which will
|
||||
;; be expanded into a proper documentation string upon call of `documentation'.
|
||||
|
@ -491,17 +488,15 @@
|
|||
|
||||
;; @@@ Argument list mapping:
|
||||
;; ==========================
|
||||
;; Because `defadvice' allows the specification of the argument list of the
|
||||
;; advised function we need a mapping mechanism that maps this argument list
|
||||
;; onto that of the original function. For example, somebody might specify
|
||||
;; `(sym newdef)' as the argument list of `fset', while advice might use
|
||||
;; `(&rest ad-subr-args)' as the argument list of the original function
|
||||
;; (depending on what Emacs version is used). Hence SYM and NEWDEF have to
|
||||
;; be properly mapped onto the &rest variable when the original definition is
|
||||
;; called. Advice automatically takes care of that mapping, hence, the advice
|
||||
;; programmer can specify an argument list without having to know about the
|
||||
;; exact structure of the original argument list as long as the new argument
|
||||
;; list takes a compatible number/magnitude of actual arguments.
|
||||
;; Because `defadvice' allows the specification of the argument list
|
||||
;; of the advised function we need a mapping mechanism that maps this
|
||||
;; argument list onto that of the original function. Hence SYM and
|
||||
;; NEWDEF have to be properly mapped onto the &rest variable when the
|
||||
;; original definition is called. Advice automatically takes care of
|
||||
;; that mapping, hence, the advice programmer can specify an argument
|
||||
;; list without having to know about the exact structure of the
|
||||
;; original argument list as long as the new argument list takes a
|
||||
;; compatible number/magnitude of actual arguments.
|
||||
|
||||
;; @@ Activation and deactivation:
|
||||
;; ===============================
|
||||
|
@ -884,9 +879,6 @@
|
|||
;; @@ Summary of forms with special meanings when used within an advice:
|
||||
;; =====================================================================
|
||||
;; ad-return-value name of the return value variable (get/settable)
|
||||
;; ad-subr-args name of &rest argument variable used for advised
|
||||
;; subrs whose actual argument list cannot be
|
||||
;; determined (get/settable)
|
||||
;; (ad-get-arg <pos>), (ad-get-args <pos>),
|
||||
;; (ad-set-arg <pos> <value>), (ad-set-args <pos> <value-list>)
|
||||
;; argument access text macros to get/set the values of
|
||||
|
@ -2594,36 +2586,6 @@ For that it has to be fbound with a non-autoload definition."
|
|||
(byte-compile symbol)
|
||||
(fset function (symbol-function symbol))))))
|
||||
|
||||
|
||||
;; @@ Constructing advised definitions:
|
||||
;; ====================================
|
||||
;;
|
||||
;; Main design decisions about the form of advised definitions:
|
||||
;;
|
||||
;; A) How will original definitions be called?
|
||||
;; B) What will argument lists of advised functions look like?
|
||||
;;
|
||||
;; Ad A)
|
||||
;; I chose to use function indirection for all four types of original
|
||||
;; definitions (functions, macros, subrs and special forms), i.e., create
|
||||
;; a unique symbol `ad-Orig-<name>' which is fbound to the original
|
||||
;; definition and call it according to type and arguments. Functions and
|
||||
;; subrs that don't have any &rest arguments can be called directly in a
|
||||
;; `(ad-Orig-<name> ....)' form. If they have a &rest argument we have to
|
||||
;; use `apply'. Macros will be called with
|
||||
;; `(macroexpand '(ad-Orig-<name> ....))', and special forms also need a
|
||||
;; form like that with `eval' instead of `macroexpand'.
|
||||
;;
|
||||
;; Ad B)
|
||||
;; Use original arguments where possible and `(&rest ad-subr-args)'
|
||||
;; otherwise, even though this seems to be more complicated and less
|
||||
;; uniform than a general `(&rest args)' approach. My reason to still
|
||||
;; do it that way is that in most cases my approach leads to the more
|
||||
;; efficient form for the advised function, and portability (e.g., to
|
||||
;; make the same advice work regardless of whether something is a
|
||||
;; function or a subr) can still be achieved with argument access macros.
|
||||
|
||||
|
||||
(defun ad-prognify (forms)
|
||||
(cond ((<= (length forms) 1)
|
||||
(car forms))
|
||||
|
|
Loading…
Add table
Reference in a new issue