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

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

+2
Clojure

如果您使用 with-redefs 来重新定义一个宏(这可能是错误的做法),则在 with-redefs 调用完成后,该宏会失去宏状态。

修复方案可能取决于我们是否认为在宏上使用 with-redefs 是有效的用途(这只能在 body 中调用 eval 或等效函数的情况下有效,需要了解您正在做什么以将两个额外的宏参数添加到函数中)--如果是这样,我们将阻止它失去宏状态;如果不是,如果您意外地在一个宏上使用它,我们可能还会抛出一个异常。

效果演示

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

'user/kwote

user> (kwote hello)
hello
user> kwote
编译器异常:不能获取宏的值:#'user/kwote,编译:(/tmp/form-init6222001939841513290.clj:1:18983)

; 以上内容均如预期

user> (with-redefs [kwote (constantly :in-with-redefs)] (kwote with-redefs-body))
with-redefs-body
user> (kwote hello)
编译器异常:无法解析符号:hello 在此上下文中,编译:(/tmp/form-init6222001939841513290.clj:1:1)
user> (kwote :arg-1)
参数异常:传递给:user/kwote 的参数数量不对(1) clojure.lang.AFn.throwArity (AFn.java:429)
user> (kwote :arg-1 :arg-2 :arg-3)
(quote :arg-3)
user> kwote

对象[user$kwote 0x37e32ff6 "user$kwote@37e32ff6"]

`

2 答案

0

由:gfredericks 发布的评论

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

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