0

I have the following in a file "constraint.clj" starting at line 49 (shown with line numbers):

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))

From nrepl, I compile the file. When I inspect the value at s, it shows.

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

So, basically, it seems to work pretty well, except that the getMethodName is not what I expected. I would like :name to be app.constraint/stacker. How do I do that?

4

1 回答 1

2

在内部,Clojureclojure.lang.AFn为每个匹配模式“namespace$function-name”的函数生成一个 Java 类。当一个函数被执行时,调用该对象的调用方法,具有正确的数量。

你可以在这里找到源代码: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 回答