5

コンテクスト

現在、

(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_を取得するにはどうすればよいですか?

ありがとう。

4

2 に答える 2

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))
于 2012-06-09T03:18:52.750 に答える
0

log4jlogbackなどのJavaロギングフレームワークは、この種の機能を提供します。ログメッセージに行番号を追加するようにロギングシステムを設定できます。ファイル名はもっと難しいかもしれませんが、少なくともそこに名前空間を持つことができます。

clojure.loggingを使用して、ロギングフレームワークへの優れたインターフェースを提供できます。

于 2012-07-15T07:21:19.520 に答える