Clojure宏堆栈异常跟踪
假设我有一个宏,它将所有出现的“transact”替换为“\”,如下所示:Clojure宏堆栈异常跟踪,clojure,Clojure,假设我有一个宏,它将所有出现的“transact”替换为“\”,如下所示: (defmacro transmuting-macro [& body] (let [transmuted-body (clojure.walk/postwalk #(if (and (list? %) (= 'transact (first %))) (-> % rest (conj `/))
(defmacro transmuting-macro [& body]
(let [transmuted-body (clojure.walk/postwalk
#(if (and (list? %) (= 'transact (first %)))
(-> % rest (conj `/)) %) body)]
transmuted-body))
现在我可以做到:
(defn generate-error []
(transmuting-macro (let [x 1
b (transact 1 3)]
(transact 3 0))))
但异常的stacktrace无法跟踪内部内容,它在宏调用时停止(第2行),然后立即跳转到除法,而不提供任何有意义的行号(在本例中为第4行)
如果我只在宏定义的最后一行中放置body
而不是transmutedbody
,堆栈将被保留。因此,我认为,在某些地方有一些隐藏的信息,允许编译器内省一些宏,而不是其他宏。
我试着研究meta、special&form和&env变量,但都没有用。
因为我的变形不会改变行号,所以复制这些信息就足够了。如何使其工作?查看
macroexpand
我觉得您的宏写错了。
我不知道你是如何引发异常的,所以你可以尝试这个变体,它的扩展更加正确
(定义宏转换宏[&body]
(让[变形的身体(clojure.walk/postwalk
#(如果(和(列表%)(='交易(第一个%))
(>%rest(conj`/)%)body)]
`(do~@变形体)))
查看macroexpand
我觉得您的宏写错了。
我不知道你是如何引发异常的,所以你可以尝试这个变体,它的扩展更加正确
(定义宏转换宏[&body]
(让[变形的身体(clojure.walk/postwalk
#(如果(和(列表%)(='交易(第一个%))
(>%rest(conj`/)%)body)]
`(do~@变形体)))