Emacs Lisp: How to use ad-get-arg and ad-get-args?

耗尽温柔 提交于 2019-12-11 01:51:58

问题


I'm not sure I am using ad-get-args and ad-get-arg right.

For example, the following code doesn't work.

(defun my-add (a b)
  (+ a b))
(defadvice my-add (after my-log-on activate)
  (message "my-add: %s" (ad-get-args)))
(my-add 1 2)

The last expression causes an error:

Debugger entered--Lisp error: (void-function ad-get-args).

The following doesn't work either.

(defun my-substract (a b)
  (- a b))
(defadvice my-substract (around my-log-on activate)
  (message "my-substract: %s" (ad-get-arg 0))
  (ad-do-it))
(my-substract 10 1)

The defadvice gives a warning:

Warning: `(setq ad-return-value (ad-Orig-my-substract a b))' is a malformed
    function

And the last expression gives an error:

Debugger entered--Lisp error: (invalid-function (setq ad-return-value (ad-Orig-my-substract a b)))
  (setq ad-return-value (ad-Orig-my-substract a b))()

I was trying to use defadvice to watch start-process arguments for debugging purposes and I found my way of using ad-get-arg didn't work.

Update: Answer,

From the answers it turns out that I should have used (ad-get-args 0) instead of (ad-get-args) in (defadvice my-add ..), and I should have used ad-do-it instead of (ad-do-it) in in (defadvice my-substract ..). And it's better to use trace-function.


回答1:


You have two problems in your code. First (as you noted), you're using ad-get-args incorrectly. The docs say:

(ad-get-args <position>) will return the list of actual arguments supplied starting at <position>.

It looks like what you want is:

(defadvice my-add (after my-log-on activate)
  (message "my-add: %s" (ad-get-args 0)))

In your my-subtract, the problem is your use of ad-do-it, you have it surrounded by parentheses, it should not be. This is the correct use:

(defadvice my-substract (around my-log-on activate)
  (message "my-substract: %s" (ad-get-arg 0))
  ad-do-it)

From the docs in the advice library:

An around advice can specify where the forms of the wrapped or surrounded forms should go with the special keyword ad-do-it, which will be substituted with a progn containing the forms of the surrounded code.

The best tutorial and introduction to advice I've found is in the advice library itself (in the comments in the beginning).

M-x find-library advice RET



回答2:


This works:

(defun my-add (a b) 
  (+ a b))

(defadvice my-add (after my-log-on activate) 
  (message "my-add: %d %d" (ad-get-arg 0) (ad-get-arg 1)))

(my-add 1 2) 

You have to consider the type of the argument you are retrieving, when passing it to the message function. I think the errors you are getting are obscured by the fact that they occur within advice. If the errors were not in advice, you'd see a clearer message, indicating a type mismatch.

When in doubt, or when you are passing an arg that is not a string to message, use (prin1-to-string arg)

like this:

(defadvice my-add (after my-log-on activate) 
  (message "my-add: %s %s"
           (prin1-to-string (ad-get-arg 0))
           (prin1-to-string (ad-get-arg 1))))



回答3:


There is no need to use ad-get-arg, you can use the same names in the body of the advice:

(defun my-add (a b)
  (+ a b))
(defadvice my-add (after my-add-log activate)
  (message "my-add: %d %d" a b))

Update:

If you just want to trace function calls for debugging purpose, emacs can generate a proper trace advice for you:

(defun my-add (a b)
  (+ a b))
(trace-function 'my-add) 


来源:https://stackoverflow.com/questions/2622351/emacs-lisp-how-to-use-ad-get-arg-and-ad-get-args

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!