2011-08-20 36 views
5

Tôi đang cố gắng thêm thuộc tính "thông báo" tùy chọn vào macro thời gian Clojure. Về cơ bản tôi muốn thêm một tin nhắn tùy chỉnh tùy chọn vào đầu ra của thời gian. Tôi đang cố gắng tìm một nút cổ chai trong chương trình của tôi và có một số thông điệp mô tả gắn liền với đầu ra của thời gian sẽ rất hữu ích.Thêm đối số tùy chọn vào macro

Tôi đã thử những điều sau đây:

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

Cả hai trường hợp ngoại lệ ném. Làm cách nào để tôi thực hiện công việc này?

Trả lời

4

Nó ném một ngoại lệ vì msg là một danh sách,

nói rằng bạn gọi nó với,

(time (+ 1 1) "asd") 

msg trong vĩ mô trở thành một cuộc gọi chức năng, ("asd") mà thất bại. Chỉ cần destructure msg,

[expr & [msg]] 

và sử dụng

~msg 

Bạn cũng có thể kiểm tra như thế nào macro được mở rộng với macroexpand,

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

Cũng vài điểm,

  • thời gian đã có trong lõi
  • phiên bản của bạn chỉ chấp nhận và lần hiển thị một lần.

EDIT: thời gian với thông điệp tùy chọn,

 

(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

Tôi đã sử dụng phiên bản lõi, tuy nhiên đối với trường hợp này là một thông điệp debug sẽ thực sự hữu ích cho tôi. Có cách nào tốt hơn để làm điều này? Có lẽ một số loại wrapper macro? Không phải là phiên bản lõi chỉ chấp nhận một biểu hiện duy nhất là tốt? – erikcw

+0

@erikcw Có bạn là đúng phiên bản lõi xấu của tôi cũng chấp nhận một đối số duy nhất. cũng đã thêm một phiên bản với một đối số tùy chọn –

Các vấn đề liên quan