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
编译器异常 java.lang.RuntimeException:不能取宏的值:#'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)
编译器异常 java.lang.RuntimeException:在此上下文中无法解析符号: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报告)
...