目前,
(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_?
感谢。
答案 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)
log4j和logback等Java日志框架提供了这种功能。您可以配置日志记录系统以将行号添加到日志消息中。文件名可能更难,但至少你可以在那里拥有命名空间。
您可以使用clojure.logging为日志框架提供良好的界面。