Clojure:调试Println,__LINE_NUMBER__和__FILE_NAME__

use*_*359 5 clojure

上下文

目前,

(println "x is" x)
Run Code Online (Sandbox Code Playgroud)

打印出来

x is 10
Run Code Online (Sandbox Code Playgroud)

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

(my-println "x is" x)
Run Code Online (Sandbox Code Playgroud)

打印出来:

foo.clj:23> x is 10
Run Code Online (Sandbox Code Playgroud)

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

题:

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

谢谢.

ama*_*loy 10

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

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

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

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

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