5

Context

Currently,

(println "x is" x)

just prints out

x is 10

Now, what I want is something like this:

(my-println "x is" x)

to print out:

foo.clj:23> x is 10

Informally, I want my-println to append the _FILE_NAME_ and _LINE_NUMBER_ into my println.

Question:

I know how to use macros. However, I don't know how to extract the _FILE_NAME_ and _LINE_NUMBER_ from the current location in Clojure (whereas C macros make this trivial to do). How do I get the current FILE_NAME_ and _LINE_NUMBER_ ?

Thanks.

2 Answers 2

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

Looking at this answer again much later, you can be a bit more clever if you like, reducing the runtime costs by interpolating the string constants at compile time:

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

As you can see from the macroexpansion, there is no longer any need to invoke relatively-expensive printf code at runtime:

(let [x 5] (macroexpand '(my-println (+ x 5))))
(clojure.core/println "foo.clj:1> (+ x 5) is" (+ x 5))
Sign up to request clarification or add additional context in comments.

2 Comments

whoa, I didnt' know clojure had printf -- no more crap like (println (apply str .... ))
if use lein run -m your.main.class or clojure.main -m your.main.class, the *file* is nil.
0

Java logging frameworks like log4j and logback provide this kind of functionality. You can configure logging system to add the line numbers to log messages. File name may be more difficult, but at least you can have the namespace there.

You can use clojure.logging to provide nice interface to the logging frameworks.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.