1

私の質問は、Clojureプログラムのソースコードメタデータが存在し、簡単にアクセスできるかどうかです。

呼び出す関数、デバッグフラグ、およびデバッグフラグが設定されたときに出力する任意のテキスト(たとえば、ソースコード内の呼び出しの場所)を受け入れる関数ラッパーを作成することを考えていました。クリアすると、関数のみが呼び出されます。

位置をハードコーディングするのではなく、現在実行中の関数からそれを収集できるかどうか疑問に思いました。そのような情報が利用できるかどうかはわかりません。そうでなければ、関数が呼び出されるところならどこでも、私は確かに任意の位置情報を提供することができます。

このような関数の例を次に示します。

(defn test-fn
    []
    (println "This is a test function."))

(defn fn-call-loc
    [fn dbg-flag & locate-info]
    (if (= 1 dbg-flag)
        (println locate-info))
    (fn))

repl-test.core=> (fn-call-loc test-fn 1 "Called from main.")
(Called from main.)
This is a test function.
nil
repl-test.core=> 

私の質問は、ハードコーディングされた「Called from main。」ではなく、fn-call-locへの呼び出しの場所での位置に関する利用可能なメタデータはありますか?

ありがとう。

4

1 に答える 1

1

There is the Metadata clojure.org docs page that talks about metadata. To do what you would like I would change fn-call-loc like this:

(defn fn-call-loc
  [fv dbg-flag]
  (if dbg-flag
    (let [n (-> (:ns (meta fv)) (.getName))
          f (:name (meta fv))
          l (:line (meta fv))]
      (println (str "Called from " n "/" f " which is defined on line " l))))
  (fv))

And you call it like this:

(fn-call-loc #'test-fn true)

or this:

(fn-call-loc (var test-fn) true)

There are some gotchas though.

  • Change all instances of 'fv' to 'fn' in fn-call-loc and your results will probably be from clojure.core, not your namespace.
  • If you pass a symbol directly you'll get an exception. The Var object is needed see the (var symbol) clojure.org docs and the Var-quote in the reader docs pages.
  • Probably some more I can't think of right now.

This might be a good place for a macro but I think that's another question.

于 2015-02-19T03:24:10.320 に答える