Clojure 堆栈跟踪和动态内部变量
Clojure stacktraces and dynamically interned vars
我有 Clojure 代码并对它求值,然后将它存入一个 var:
(let [x (binding [*ns* my-ns] (eval m-code))]
(intern my-ns my-sym x)) ; my-sym was declared beforehand.
但是当 x 内发生错误时,trace 没有引用 x:
my-ns/eval27298/fn--27299
...
我复制了一个更“标准”的变量的元数据,但这并没有改变堆栈跟踪:
(alter-meta! my-var #(assoc % :line 1 :column 1 :file "my_ns.clj" :name my-sym :ns my-ns))
如果不是元数据,用什么来确定堆栈跟踪?
除非我记错了,否则它是这样工作的:
- reader 读取您的代码并将所有位置元数据分配给 vars
- 然后对代码进行评估,元数据不仅用于报告代码加载期间的错误,还用于报告在评估本身之后使用评估的功能时发生的任何错误
鉴于此,alter-meta!
无法工作,因为所有位置都已被处理并记住。可以工作的是在上面的步骤 1 和 2 之间分配元数据:
user=> (def code "#(throw (ex-info \"\" {}))")
#'user/code
user=> (def f (eval (-> (read-string code) (with-meta {:line 42, :clojure.core/eval-file "hello.clj"}))))
#'user/f
user=> (f)
Execution error (ExceptionInfo) at user/eval175$fn (hello.clj:42).
请注意,我使用 :clojure.core/eval-file
来指定文件,而不仅仅是 :file
。
我有 Clojure 代码并对它求值,然后将它存入一个 var:
(let [x (binding [*ns* my-ns] (eval m-code))]
(intern my-ns my-sym x)) ; my-sym was declared beforehand.
但是当 x 内发生错误时,trace 没有引用 x:
my-ns/eval27298/fn--27299
...
我复制了一个更“标准”的变量的元数据,但这并没有改变堆栈跟踪:
(alter-meta! my-var #(assoc % :line 1 :column 1 :file "my_ns.clj" :name my-sym :ns my-ns))
如果不是元数据,用什么来确定堆栈跟踪?
除非我记错了,否则它是这样工作的:
- reader 读取您的代码并将所有位置元数据分配给 vars
- 然后对代码进行评估,元数据不仅用于报告代码加载期间的错误,还用于报告在评估本身之后使用评估的功能时发生的任何错误
鉴于此,alter-meta!
无法工作,因为所有位置都已被处理并记住。可以工作的是在上面的步骤 1 和 2 之间分配元数据:
user=> (def code "#(throw (ex-info \"\" {}))")
#'user/code
user=> (def f (eval (-> (read-string code) (with-meta {:line 42, :clojure.core/eval-file "hello.clj"}))))
#'user/f
user=> (f)
Execution error (ExceptionInfo) at user/eval175$fn (hello.clj:42).
请注意,我使用 :clojure.core/eval-file
来指定文件,而不仅仅是 :file
。