从stacktrace(clojure)获取封闭方法的名称?

时间:2013-09-14 03:16:43

标签: clojure

我在第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不是我所期望的。我希望:nameapp.constraint/stacker。我该怎么做?

1 个答案:

答案 0 :(得分:2)

在内部,Clojure为每个与“namespace $ function-name”模式匹配的函数生成一个继承自clojure.lang.AFn的Java类。执行函数时,将使用正确的arity在该对象上调用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)