summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChong Yidong <cyd@gnu.org>2013-12-26 11:27:45 +0800
committerChong Yidong <cyd@gnu.org>2013-12-26 11:27:45 +0800
commit2200a8c91de23f9749d1b3c961c4f8bb3145ddfa (patch)
treedd578714cbecc18cc93573e33e68c982f204a120
parented88fb10f41ee1501a1d5c1c9eb005c18285acc6 (diff)
downloademacs-2200a8c91de23f9749d1b3c961c4f8bb3145ddfa.tar.gz
emacs-2200a8c91de23f9749d1b3c961c4f8bb3145ddfa.tar.bz2
emacs-2200a8c91de23f9749d1b3c961c4f8bb3145ddfa.zip
Update doc for advice changes.
* doc/lispref/advice.texi (Advising Functions, Defining Advice): Special forms can no longer be advised. * lisp/emacs-lisp/advice.el: Update commentary.
-rw-r--r--doc/lispref/ChangeLog5
-rw-r--r--doc/lispref/advice.texi77
-rw-r--r--etc/NEWS7
-rw-r--r--lisp/emacs-lisp/advice.el28
4 files changed, 51 insertions, 66 deletions
diff --git a/doc/lispref/ChangeLog b/doc/lispref/ChangeLog
index 354efd5f40c..2956b907d77 100644
--- a/doc/lispref/ChangeLog
+++ b/doc/lispref/ChangeLog
@@ -1,3 +1,8 @@
+2013-12-26 Chong Yidong <cyd@gnu.org>
+
+ * advice.texi (Advising Functions, Defining Advice): Special forms
+ can no longer be advised.
+
2013-12-25 Chong Yidong <cyd@gnu.org>
* keymaps.texi (Active Keymaps): Re-organize the text.
diff --git a/doc/lispref/advice.texi b/doc/lispref/advice.texi
index e8d1bd3cdbc..122f1805c1e 100644
--- a/doc/lispref/advice.texi
+++ b/doc/lispref/advice.texi
@@ -6,41 +6,43 @@
@chapter Advising Emacs Lisp Functions
@cindex advising functions
- The @dfn{advice} feature lets you add to the existing definition of
-a function, by @dfn{advising the function}. This is a cleaner method
-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}, 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.
-
- 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.
-
- 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'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.
-
- 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.
+ The @dfn{advice} feature lets you add to the existing definition of
+a function, by @dfn{advising the function}. A function can have
+multiple @dfn{pieces of advice}, each of which can be separately
+defined, and separately enabled or disabled (@pxref{Activation of
+Advice}). Each piece of advice can alter almost anything about the
+function, including its argument list, what the function does when it
+runs, and the value it returns.
+
+ Advice can be useful for altering the behavior of 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.
+
+ 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
+(@pxref{Hooks}). 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 (@pxref{Remapping Commands}).
+In particular, 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.)
+
+ Macros can also be advised, in much the same way as functions.
+However, special forms (@pxref{Special Forms}) cannot be advised.
+
+ It is possible to advise a primitive (@pxref{What Is a Function}),
+but one should typically @emph{not} 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.
@menu
* Simple Advice:: A simple example to explain the basics of advice.
@@ -140,10 +142,9 @@ syntax of @code{defun} and @code{defmacro}, but adds more:
@end example
@noindent
-Here, @var{function} is the name of the function (or macro or special
-form) to be advised. From now on, we will write just ``function'' when
-describing the entity being advised, but this always includes macros and
-special forms.
+Here, @var{function} is the name of the function (or macro) to be
+advised. From now on, we will write just ``function'' when describing
+the entity being advised, but this always includes macros.
In place of the argument list in an ordinary definition, an advice
definition calls for several different pieces of information.
diff --git a/etc/NEWS b/etc/NEWS
index de461aa2bf7..5aedab61c20 100644
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -901,9 +901,10 @@ value when looking up variables.
** `defadvice' does not honor the `freeze' flag and cannot advise
special-forms any more.
-** `dolist' in lexical-binding mode does not bind VAR in RESULT any more.
-VAR was bound to nil which was not tremendously useful and just lead to
-spurious warnings about an unused var.
+---
+** `dolist' no longer binds VAR while evaluating the RESULT form,
+when lexical binding is enabled. Previously, VAR was bound to nil,
+which often led to spurious unused-variable warnings.
** The return value of `backup-buffer' has changed.
The second argument is no longer an SELinux context, instead it is an
diff --git a/lisp/emacs-lisp/advice.el b/lisp/emacs-lisp/advice.el
index 7996f9a2263..f2d5ce9a11e 100644
--- a/lisp/emacs-lisp/advice.el
+++ b/lisp/emacs-lisp/advice.el
@@ -295,8 +295,8 @@
;; {<after-K-1-body-form>}*
;; ad-return-value))
-;; Macros and special forms will be redefined as macros, hence the optional
-;; [macro] in the beginning of the definition.
+;; Macros are redefined as macros, hence the optional [macro] in the
+;; beginning of the definition.
;; <arglist> is either the argument list of the original function or the
;; first argument list defined in the list of before/around/after advices.
@@ -698,6 +698,7 @@
;; problems because they get expanded at compile or load time, hence, they
;; might not have all the necessary runtime support and such advice cannot be
;; de/activated or changed as it is possible for functions.
+;;
;; Special forms cannot be advised.
;;
;; MORAL: - Only advise macros when you are absolutely sure what you are doing.
@@ -1563,29 +1564,6 @@
;; flexibility and effectiveness of the advice mechanism. Macros that were
;; compile-time expanded before the advice was activated will of course never
;; exhibit the advised behavior.
-;;
-;; @@ Advising special forms:
-;; ==========================
-;; Now for something that should be even more rare than advising macros:
-;; Advising special forms. Because special forms are irregular in their
-;; argument evaluation behavior (e.g., `setq' evaluates the second but not
-;; the first argument) they have to be advised into macros. A dangerous
-;; consequence of this is that the byte-compiler will not recognize them
-;; as special forms anymore (well, in most cases) and use their expansion
-;; rather than the proper byte-code. Also, because the original definition
-;; of a special form cannot be `funcall'ed, `eval' has to be used instead
-;; which is less efficient.
-;;
-;; MORAL: Do not advise special forms unless you are completely sure about
-;; what you are doing (some of the forward advice behavior is
-;; implemented via advice of the special forms `defun' and `defmacro').
-;; As a safety measure one should always do `ad-deactivate-all' before
-;; one byte-compiles a file to avoid any interference of advised
-;; special forms.
-;;
-;; Apart from the safety concerns advising special forms is not any different
-;; from advising plain functions or subrs.
-
;;; Code: