2011-08-20 15 views
5

Sto tentando di aggiungere un attributo "messaggio" alla macro del tempo Clojure. Fondamentalmente voglio aggiungere un messaggio personalizzato opzionale all'output del tempo. Sto cercando di trovare un collo di bottiglia nel mio programma e avere dei messaggi descrittivi collegati all'output del tempo sarebbe molto utile.Aggiunta di argomenti facoltativi alla macro

ho provato la seguente:

;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#)) 

e

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

Entrambi generano eccezioni. Come faccio a fare questo lavoro?

risposta

4

viene generata un'eccezione perché msg è una lista,

dicono si chiami con,

(time (+ 1 1) "asd") 

msg nella macro diventa una chiamata di funzione, ("asd") che non riesce. Proprio destrutturare msg,

[expr & [msg]] 

e utilizzare

~msg 

Si può anche verificare come le macro sono espanse con macroexpand,

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

Anche paio di punti,

  • tempo è già nel core
  • la tua versione accetta solo e volta una singola espressione.

EDIT: il tempo con un messaggio opzionale,

 

(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

Sto usando la versione di base, ma per questo caso un messaggio di debug sarà davvero utile per me. C'è un modo migliore per farlo? Forse una specie di macro wrapper? La versione core non accetta solo una singola espressione? – erikcw

+0

@erikcw Sì, hai ragione, la mia versione di base cattiva accetta anche un singolo argomento. ha anche aggiunto una versione con un argomento opzionale –

Problemi correlati