The simplest way to access the arguments of an advised function in the body of a piece of advice is to use the same names that the function definition uses. To do this, you need to know the names of the argument variables of the original function.
While this simple method is sufficient in many cases, it has a disadvantage: it is not robust, because it hard-codes the argument names into the advice. If the definition of the original function changes, the advice might break.
Another method is to specify an argument list in the advice itself. This avoids the need to know the original function definition's argument names, but it has a limitation: all the advice on any particular function must use the same argument list, because the argument list actually used for all the advice comes from the first piece of advice for that function.
A more robust method is to use macros that are translated into the proper access forms at activation time, i.e., when constructing the advised definition. Access macros access actual arguments by position regardless of how these actual arguments get distributed onto the argument variables of a function. This is robust because in Emacs Lisp the meaning of an argument is strictly determined by its position in the argument list.
Now an example. Suppose the function foo
is defined as
(defun foo (x y &optional z &rest r) ...)
and is then called with
(foo 0 1 2 3 4 5 6)
which means that x is 0, y is 1, z is 2 and r is
(3 4 5 6)
within the body of foo
. Here is what
ad-get-arg
and ad-get-args
return in this case:
(ad-get-arg 0) => 0 (ad-get-arg 1) => 1 (ad-get-arg 2) => 2 (ad-get-arg 3) => 3 (ad-get-args 2) => (2 3 4 5 6) (ad-get-args 4) => (4 5 6)
Setting arguments also makes sense in this example:
(ad-set-arg 5 "five")
has the effect of changing the sixth argument to "five"
. If this
happens in advice executed before the body of foo
is run, then
r will be (3 4 "five" 6)
within that body.
Here is an example of setting a tail of the argument list:
(ad-set-args 0 '(5 4 3 2 1 0))
If this happens in advice executed before the body of foo
is run,
then within that body, x will be 5, y will be 4, z
will be 3, and r will be (2 1 0)
inside the body of
foo
.
These argument constructs are not really implemented as Lisp macros. Instead they are implemented specially by the advice mechanism.
Go to the first, previous, next, last section, table of contents.