2011-08-20 80 views
5

我試圖給Clojure時間宏添加一個選項「message」屬性。基本上我想添加一個可選的自定義消息的時間輸出。我試圖在我的程序中找到一個瓶頸,並且在時間輸出中附加一些描述性消息將會非常有幫助。將可選參數添加到宏

我已經試過如下:

;optional argument 
(defmacro time 
    "Evaluates expr and prints the time it took. Returns the value of 
expr." 
    {:added "1.0"} 
    [expr & msg] 
    `(let [start# (. System (nanoTime)) 
     ret# ~expr] 
    (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " (first ~msg))) 
    ret#)) 

(defmacro time 
    "Evaluates expr and prints the time it took. Returns the value of 
expr." 
    {:added "1.0"} 
    ([expr] (time expr "")) 
    ([expr msg] 
    `(let [start# (. System (nanoTime)) 
     ret# ~expr] 
    (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " ~msg)) 
    ret#))) 

兩個拋出異常。我如何完成這項工作?

回答

4

因爲味精是一個列表它拋出一個異常,

說你叫它,

(time (+ 1 1) "asd") 

味精宏成爲一個函數調用,(「ASD」),這將失敗。只是解構味精,

[expr & [msg]] 

,並使用

~msg 

您還可以測試如何宏與macroexpand展開,

(macroexpand '(time (+ 1 1) "asd")) 

而且幾個百分點,

  • 時間已經在覈心
  • 您的版本只接受和計算單個表達式。

編輯:時間可選的消息,

 

(defmacro time 
    "Evaluates expr and prints the time it took. Returns the value of 
expr." 
    {:added "1.0"} 
    [expr & [msg]] 
    (let [msg (if (nil? msg) "" msg)] 
    `(let [start# (. System (nanoTime)) 
     ret# ~expr] 
     (prn (str "Elapsed time: " (/ (double (- (. System (nanoTime)) start#)) 1000000.0) " msecs. " ~msg)) 
     ret#))) 
 
(time (+ 1 1)) 
"Elapsed time: 0.068 msecs. " 
2 

(time (+ 1 1) "asd") 
"Elapsed time: 0.067 msecs. asd" 
2 
+0

我一直在使用的核心版本,但這種情況下的調試消息將真正幫助我。有一個更好的方法嗎?也許某種包裝宏?核心版本是否只接受單一表達式? – erikcw

+0

@erikcw是的,你是對的我的不良核心版本也接受一個參數。還添加了一個帶有可選參數的版本 –