我不确定自己是否遇到某种竞争条件,但是我正在将一些测试代码放在一起测试在Clojure中使用传统的面向对象的范例,我碰到了一些有趣的行为。检查以下代码:
(def registrar (ref #{}))
(defrecord Person [first-name last-name])
(def rick (->Person "Rick" "James"))
(def charlie (->Person "Charlie" "Murphy"))
(dosync
(alter registrar conj rick)
(alter registrar conj charlie))
(defn print-record
[record]
(println (format "%s %s", (:first-name record), (:last-name record))))
(defn print-registrar
"Prints a report of the registrar to stdout"
[registrar]
(println "Registrar's Report\n------------------")
(map print-record registrar))
(let [registrar (deref registrar)]
(print-registrar registrar))
当我在REPL中运行代码时,一切正常:print-registrar
成功将记录从注册商传递到print-record
,并按预期打印,如下:
Registrar's Report
------------------
Rick James
Charlie Murphy
(nil nil)
但是当我尝试从命令行运行代码时,我得到以下内容:
Registrar's Report
------------------
这是因为dosync
是异步调用还是其他什么?当我在致电map
之前转储注册商的内容时,我会看到我对它的期望,所以我有点困惑。
答案 0 :(得分:2)
将map
与副作用混合起来通常不是一个好主意,因为map
是懒惰的,因此副作用不会发生,除非有些东西穿过序列并且强制副作用(在这种情况下,repl会为你做这件事)。
我认为run!
应该是替代品,因为print-record
不会返回任何有用的内容。