【发布时间】:2013-12-06 04:26:17
【问题描述】:
更新帖子以使其与事件进程相关(响应和消除混乱)。
非常感谢您的宝贵时间和帮助!
在某些先前版本的 Clojure 中,每个 var 都可以使用“绑定”形式绑定。 现在,如果未定义为动态,您会得到“无法动态绑定非动态变量”。
在某些情况下,在定义后使函数 var 动态化可能很有用(测试中的存根/模拟)。
不要尝试:
(def ^{:dynamic true} log-call #'log-call)
它最终会导致 StackOverflowError,因为您正在定义一个调用自身的函数(感谢您的解释)。
更新后的问题:
建议的方法似乎不起作用。
从绑定表单调用的表单没有定义绑定。
你能帮我弄清楚我错过了什么吗??
这是更新后的代码:
(def all-expenses [{:amount 33.0 :date "today"}
{:amount 44.0 :date "yesterday"}])
(defn fetch-all-expenses [])
(defn fetch-expenses-greater-than [threshold]
(let [all (fetch-all-expenses)]
;calling from a nested form does not see the dynamically bound definition!
(println "2) from fetch-expenses-greater-than:" (fetch-all-expenses))
all))
(defn wrap [f]
(fn [& args] (apply f args)))
(def ^{:dynamic true} fetch-all-expenses (wrap fetch-all-expenses))
(binding [fetch-all-expenses (constantly all-expenses)]
(let [filtered (fetch-expenses-greater-than 15.0)]
(println "1) from inside binding:" (fetch-all-expenses))));calling from binding form OK!
repl中执行的结果是:
2) from fetch-expenses-greater-than: nil
1) from inside binding: [{:date today, :amount 33.0} {:date yesterday, :amount 44.0}]
nil
如果我将 fetch-all-expenses 的定义更改为
(defn ^:dynamic fetch-all-expenses [])
结果如预期:
2) from fetch-expenses-greater-than: [{:date today, :amount 33.0} {:date yesterday, :amount 44.0}]
1) from inside binding: [{:date today, :amount 33.0} {:date yesterday, :amount 44.0}]
nil
【问题讨论】:
-
关于问题 3)我的代码有什么问题?我的行
(def ^{:dynamic true} log-call #'log-call)产生(meta #'log-call) {:ns #<Namespace user>, :name log-call, :dynamic true, :column 1, :line 19, :file "NO_SOURCE_PATH"}并且与定义函数时仅添加元数据不同。(defn ^:dynamic log-call [id] (println "Audit - called" id))产生{:arglists ([id]), :ns #<Namespace user>, :name log-call, :dynamic true, :column 1, :line 4, :file "NO_SOURCE_PATH"}所以,我的方法(问题 1)有缺陷或不完整。