2011-08-20 25 views
5

Estoy tratando de agregar un atributo de opción de "mensaje" a la macro de tiempo de Clojure. Básicamente, quiero agregar un mensaje personalizado opcional a la salida del tiempo. Estoy tratando de encontrar un cuello de botella en mi programa y tener algunos mensajes descriptivos adjuntos a la salida del tiempo sería muy útil.Agregando un argumento opcional a la macro

He intentado lo siguiente:

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

y

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

Ambas excepciones tiro. ¿Cómo hago que esto funcione?

Respuesta

4

Se lanza una excepción porque msg es una lista,

que usted llama con,

(time (+ 1 1) "asd") 

msg en la macro se convierte en una llamada de función, ("TEA") que fallen. Sólo desestructuran msg,

[expr & [msg]] 

y utilizar

~msg 

También puede probar cómo las macros se expanden con macroexpand,

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

También par de puntos,

  • tiempo ya está en el núcleo
  • su versión solo acepta y multiplica por una sola expresión.

EDIT: el tiempo con el mensaje opcional,

 

(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

He estado usando la versión de la base, sin embargo, para este caso un mensaje de depuración va a ser muy útil para mí. ¿Hay una mejor manera de hacer esto? Tal vez algún tipo de macro envoltura? ¿La versión central no solo acepta una sola expresión también? – erikcw

+0

@erikcw Sí, tienes razón, mi versión de núcleo malo también acepta un único argumento. también agregó una versión con un argumento opcional –

Cuestiones relacionadas