【问题标题】:Clojure stacktraces and dynamically interned varsClojure 堆栈跟踪和动态实习变量
【发布时间】:2021-11-14 03:38:05
【问题描述】:

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

如果不是元数据,用什么来确定堆栈跟踪?

【问题讨论】:

    标签: clojure stack-trace


    【解决方案1】:

    除非我弄错了,否则它是这样工作的:

    1. 阅读器读取您的代码并将所有位置元数据分配给 vars
    2. 然后对代码进行评估,元数据不仅用于报告代码加载期间的错误,还用于报告在评估本身之后使用评估的功能时发生的任何错误

    鉴于此,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

    【讨论】:

    • 它似乎只关心 :eval 文件和 :line (和 :column)。看起来 eval 在某种程度上是硬编码的。
    • 另外,我不知道 :eval-file 除了打印输出还有什么作用,因为它在 compilier.java 中使用。
    猜你喜欢
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 2012-05-26
    • 1970-01-01
    • 2011-05-25
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多