0

49行目から始まるファイル「constraint.clj」に次のものがあります(行番号で表示):

49 (defn stacker []
50   (let [s (first (.getStackTrace (new java.lang.Throwable)))]
51     {:name (.getMethodName s)
52      :file (.getFileName s)
53      :line (.getLineNumber s)}))
54 
55 (def s (stacker))

nrepl から、ファイルをコンパイルします。s の値を調べると、それが表示されます。

app.constraint> s
{:name "invoke", :file "constraint.clj", :line 50}

したがって、基本的には、getMethodName が私が期待したものではないことを除いて、かなりうまく機能しているようです。私はなりたい:nameですapp.constraint/stacker。それ、どうやったら出来るの?

4

1 に答える 1

2

clojure.lang.AFn内部的に、Clojureはパターン「namespace$function-name」に一致する各関数を継承する Java クラスを生成します。関数が実行されると、invoke メソッドがそのオブジェクトに対して正しいアリティで呼び出されます。

ここでソースを見つけることができます: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/AFn.java

元のメソッドが必要な場合は、Java スタック トレースから、生成されたクラス名を確認できます。

(defn stacker []
  (let [s (first (.getStackTrace (new java.lang.Throwable)))]
    {:name (clojure.main/demunge (.getClassName s))
     :file (.getFileName s)
     :line (.getLineNumber s)}))

(stacker) ;=> {:name "app.constraint/stacker", :file "constraint.clj", :line 50}

この情報は、関数のメタデータから直接入手することもできます。

(meta #'stacker)
于 2013-09-14T05:15:27.030 に答える