2011-08-20 35 views
5

Clojure zaman makrosuna bir seçenek "ileti" özniteliği eklemeye çalışıyorum. Temel olarak, zamanın çıkışına isteğe bağlı bir özel mesaj eklemek istiyorum. Programımda bir darboğaz bulmaya çalışıyorum ve zamanın çıktısına bağlı bazı açıklayıcı mesajlar çok yararlı olacaktır.Makroya isteğe bağlı değişken ekleme

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

ve

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

Hem istisnalar atar:

aşağıdaki denedim. Bu işi nasıl yaparım?

cevap

4

msg bir liste olduğu için bir istisna atar,

makro

(time (+ 1 1) "asd") 

msg başarısız bir işlev çağrısı, ("asd") olur, sen ile derim. Sadece destructure msj,

[expr & [msg]] 

ve ayrıca macroexpand ile genişletilir nasıl makro test edebilirsiniz

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

puan Ayrıca çift,

  • zaman

    ~msg 
    

    kullanmak zaten çekirdekte

  • versiyonunuz sadece bir ifadeyi kabul eder ve kez gönderir.

DÜZENLEME: İsteğe bağlı mesajla sefer, çekirdek sürümünü kullanıyorum

 

(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

, ancak bu durum için bir hata ayıklama mesajı benim için gerçekten yararlı olacaktır. Bunu yapmanın daha iyi bir yolu var mı? Belki bir çeşit sarıcı makrosu? Çekirdek sürümü sadece tek bir ifadeyi kabul etmiyor mu? – erikcw

+0

@erikcw Evet haklısınız, benim kötü çekirdekli versiyonum da tek bir argümanı kabul ediyor. ayrıca isteğe bağlı bir argümana sahip bir versiyon ekledi –