Clojure 模仿中的狡猾行为*
我有以下代码:Clojure 模仿中的狡猾行为*,clojure,mocking,Clojure,Mocking,我有以下代码: (def x 10) (def io (java.io.StringWriter.)) (with-redefs [x 11] (with-redefs [io (java.io.StringWriter.)] (.write io "one")) (with-redefs [io (java.io.StringWriter.)] (.write io "two") (.toString io))) (with-redefs [x 11]
(def x 10)
(def io (java.io.StringWriter.))
(with-redefs [x 11]
(with-redefs [io (java.io.StringWriter.)]
(.write io "one"))
(with-redefs [io (java.io.StringWriter.)]
(.write io "two")
(.toString io)))
(with-redefs [x 11]
(with-redefs [*out* (java.io.StringWriter.)]
(print "one"))
(with-redefs [*out* (java.io.StringWriter.)]
(print "two")
(.toString *out*)))
第一个redefs块按预期返回“2”。第二个返回“onetwo”。这就好像出于某种原因,它正在重新利用同样的被嘲笑的**out*。这是预期的行为吗?问题是您关心的
*out*
是一个线程本地值,而不是根值。尝试:
(with-redefs [x 11]
(binding [*out* (java.io.StringWriter.)]
(print "one"))
(binding [*out* (java.io.StringWriter.)]
(print "two")
(.toString *out*)))
带有redefs的
宏只改变根绑定;任何线程本地绑定都不受影响。当REPL服务器执行代码时,它是在将*out*
重新绑定到特定于客户端的写入程序的上下文中执行的,这样就可以捕获输出并将其发送回客户端进行显示(否则它将转到服务器的stdout)。如果从命令行而不是REPL运行,原始代码可能会工作。值得一提的是out str宏,其中out绑定到新的StringWriter。第二个块不返回“onetwo”-它打印“onetwo”,并将默认对象返回到PrintWriter对象的字符串表示形式。好的,它打印“onetwo”。但它也返回“onetwo”。请参阅:(=“onetwo”(带redefs[x11](带redefs[out(java.io.StringWriter.))(打印“one”)(带redefs[out(java.io.StringWriter.)](打印“two”)(.toString out)))返回true。那么,在我们的REPL版本中可能会有所不同。这在我的回复中不起作用。