我正在尝试执行以下操作: 1.我有多个代理是包含表达式的地图。 (见前三行代码)
我想要的是,在let范围内的给定日期,上面的表达式应该绑定到本地日期。 (其余部分)
我做错了什么,我应该如何处理这个问题?感谢。
---以下所有代码
(def dates [20171002 20171003])
(def date 20171002)
(def data (zipmap dates (repeatedly (count dates) #(ref {:entry true :exit true} )) ))
(dosync (alter (data 20171003) assoc-in [:entry] false))
(println data)
(def agent-1 {:entry-condition '((data date) :entry)})
;(eval (:entry-condition agent-1))
;(data date)
(def date-given 20171003)
(let [date date-given
enter? (eval (:entry-condition agent-1))]
(if enter? (println "hi") (println "correct")))
;; i need correct, not hi.
答案 0 :(得分:1)
首先,+1给@amalloy评论此eval不是你在这里的朋友(some say evil)。
问题的根本原因是 eval在当前命名空间中查找而不是当前词法范围。这在this answer进一步解释。
因此,要重新绑定date
,您需要使用binding而不是let(至少对于日期符号)。然后它也需要是动态的。在你的日期定义中,你可以通过以下方式使其变得动态:
(def ^:dynamic date 20171002)
;; or better yet:
(declare ^:dynamic date)
然后当你使用它时,
(binding [date date-given]
(let [enter? (eval (:entry-condition agent-1))]
(if enter?
(println "NO")
(println "correct") )) )