2024 年 Clojure 状态调查! 分享您的想法。

欢迎!请参阅 关于 页面以获取更多关于如何运作的信息。

+2
Clojure

如果您使用 with-redefs 重新定义一个宏(这很可能是错误),则宏在 with-redefs 调用完成后将失去其宏状态。

修复方法可能取决于我们认为在宏上使用 with-redefs 是否有效(您需要在函数体中调用 eval 或等效函数,并且需要了解自己足够多的信息来将两个额外的宏参数添加到您的函数中)--如果是这样,我们将保持其宏状态;如果不是,我们可能会在您错误地在宏上使用它时抛出异常。

效果演示

`
user> (defmacro kwote [arg] `(quote ~arg))

'user/kwote

user> (kwote hello)
hello
user> kwote
CompilerException java.lang.RuntimeException: Can't take value of a macro: #'user/kwote, compiling:(/tmp/form-init6222001939841513290.clj:1:18983)

;; 上述内容都在预期之中

user> (with-redefs [kwote (constantly :in-with-redefs)] (kwote with-redefs-body))
with-redefs-body
user> (kwote hello)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: hello in this context, compiling:(/tmp/form-init6222001939841513290.clj:1:1)
user> (kwote :arg-1)
ArityException Wrong number of args (1) passed to: user/kwote clojure.lang.AFn.throwArity (AFn.java:429)
user> (kwote :arg-1 :arg-2 :arg-3)
(quote :arg-3)
user> kwote

object[user$kwote 0x37e32ff6 "user$kwote@37e32ff6"]

`

2 答案

0

评论由:gfredericks 制作

看起来根本原因是 {{with-redefs}} 使用了 1. },有意清除宏标志:[link to GitHub](https://github.com/clojure/clojure/blob/5cfe5111ccb5afec4f9c73b46bba29ecab6a5899/src/jvm/clojure/lang/Var.java#L270)

0
参考: https://clojure.atlassian.net/browse/CLJ-1867 (由 gfredericks 报告)
...