2010-04-12 38 views
2

我不確定我是否正在使用ad-get-args and ad-get-argEmacs Lisp:如何使用ad-get-arg和ad-get-args?

例如,下面的代碼不起作用。

(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) 

最後一個表達式導致錯誤:

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

下也不起作用。

(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) 

的defadvice發出警告:

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

而最後的表達提供了一個錯誤:

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))() 

我試圖用defadvice觀看啓動過程中的參數進行調試的目的我發現我使用ad-get-arg的方式不起作用。

更新:回答,

從原來的答案,我應該在(defadvice my-add ..)已經使用(ad-get-args 0)代替(ad-get-args),我應該在(defadvice my-substract ..)已經使用ad-do-it代替(ad-do-it)英寸 而且最好使用trace-function

回答

7

你在你的代碼的兩個問題。 首先(如您所述),您錯誤地使用了ad-get-args。該文件說:

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

它看起來像你想要的是:

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

在你my-subtract,問題是你使用的ad-do-it,你就用括號括起,它不應該是。這是正確的使用方法:

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

從諮詢庫中的文檔:

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.

最好的教程和介紹勸告我發現在諮詢庫本身(在意見開始)。

M-x find-library advice RET 
3

這工作:

(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) 

你必須考慮您檢索,它傳遞給消息功能時,參數的類型。我認爲你得到的錯誤被它們出現在建議中的事實所掩蓋。如果錯誤不在建議中,您會看到更清晰的消息,表明類型不匹配。

如果有疑問,或者當你傳遞一個ARG不是一個字符串message,使用(prin1-to-string arg)

這樣的:

(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)))) 
+0

表達式(消息「my-add:%s」(list 1 2))運行良好。 – Yoo 2010-04-13 12:57:00

3

沒有必要使用廣告-GET-ARG,您可以在通知的主體使用相同的名字:

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

更新

如果你只是爲了調試目的而跟蹤函數調用,emacs可以爲你生成一個合適的 跟蹤建議:

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

我不知道你可以在不提供arglist的情況下訪問args。該文檔說:「可選的參數列表可以用於定義參數列表的建議。這將成爲爲了運行建議而生成的組合定義的參數列表(請參閱組合定義)。因此,通知表達式可以使用此列表中的參數變量來訪問參數值。 ' – Cheeso 2010-04-12 15:06:38

+2

當然,直接使用參數會將參數名稱與參數名稱聯繫起來,這可能會改變... – 2010-04-12 15:39:34