Clojure:调试Println,__LINE_NUMBER__和__FILE_NAME__

时间:2012-06-08 23:49:52

标签: clojure

上下文

目前,

(println "x is" x)

打印出来

x is 10

现在,我想要的是这样的:

(my-println "x is" x)

打印出来:

foo.clj:23> x is 10

非正式地,我希望my-println将_FILE_NAME_和_LINE_NUMBER_附加到我的println中。

问题:

我知道如何使用宏。但是,我不知道如何从Clojure中的当前位置提取_FILE_NAME_和_LINE_NUMBER_(而C宏使得这很简单)。如何获取当前的FILE_NAME_和_LINE_NUMBER_?

感谢。

2 个答案:

答案 0 :(得分:10)

(defmacro my-println [x]
  `(do (printf "%s:%s> %s is %s\n"
               ~*file*
               ~(:line (meta &form))
               ~(pr-str x)
               ~x)
       (flush)))

稍后再看一下这个答案,如果你愿意,你可以更聪明一点,通过在编译时插入字符串常量来降低运行时成本:

(defmacro my-println [x]
  `(println ~(format "%s:%s> %s is"
                     *file*
                     (:line (meta &form))
                     (pr-str x))
            ~x))

从宏扩展中可以看出,不再需要在运行时调用相对昂贵的printf代码:

(let [x 5] (macroexpand '(my-println (+ x 5))))
(clojure.core/println "foo.clj:1> (+ x 5) is" (+ x 5))

答案 1 :(得分:0)

log4jlogback等Java日志框架提供了这种功能。您可以配置日志记录系统以将行号添加到日志消息中。文件名可能更难,但至少你可以在那里拥有命名空间。

您可以使用clojure.logging为日志框架提供良好的界面。