GNU Info

Info Node: (elisp)Argument Access in Advice

(elisp)Argument Access in Advice


Next: Subr Arguments Prev: Preactivation Up: Advising Functions
Enter node , (file) or (file)node

Argument Access in Advice
=========================

   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.

 - Macro: ad-get-arg position
     This returns the actual argument that was supplied at POSITION.

 - Macro: ad-get-args position
     This returns the list of actual arguments supplied starting at
     POSITION.

 - Macro: ad-set-arg position value
     This sets the value of the actual argument at POSITION to VALUE

 - Macro: ad-set-args position value-list
     This sets the list of actual arguments starting at POSITION to
     VALUE-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.


automatically generated by info2www version 1.2.2.9