4

I need to track the calls to org-tags-view to discover the params passed to it.
I tried an advice:

(defun his-tracing-function (orig-fun &rest args)
  (message "org-tags-view called with args %S" args)
  (let ((res (apply orig-fun args)))
    (message "org-tags-view returned %S" res)
    res))

(advice-add 'org-tags-view :around #'his-tracing-function)

But the return was display-buffer called with args (nil). How can I discover what params was passed for this function?

3
  • 2
    As far I can tell, your code is already correct. There was 1 param passed: nil.
    – npostavs
    Sep 5, 2016 at 18:46
  • Yes man, I think you are right! I opened the file with this function and I added some message calls and the args are nil! Thanks for your answer.
    – squiter
    Sep 5, 2016 at 19:43
  • 1
    Although your message says display-buffer was called, while you've actually added advice to org-tags-view.
    – npostavs
    Sep 5, 2016 at 19:49

3 Answers 3

6

The easiest way to find out the arguments passed to a function is to use M-x trace-function RET name-of-your-function RET. Once you're done, use M-x untrace-function or M-x untrace-all.

Note that this should work for most functions you're interested in, but there are a few corner cases. See the commentary at the top of trace.el.

0
1

You can force entering the debugger when a function is called,

(debug-on-entry 'myf)

Any calls to myf triggers the debugger. A (myf 2 3) call, for example, would result in

Debugger entered--entering a function:
* (myf 2 3)
...

Remove it when you're done,

(cancel-debug-on-entry 'list)
0

Someone else will likely answer your direct question, which is about nadvice, the "new" advice system. In case it helps you or others, this answer is about the "old" advice system (defadvice).

One reason to show it here is that this information was purged from the Elisp manual (unwisely, IMHO). It is available now only with Emacs 23 and previous builds.

Answer for the "old" advice system: Just use macro ad-get-arg or macro ad-get-args.

The (Emacs 23) Elisp manual, node Argument Access in Advice, says this:

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 their
(zero-based) 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.