看起来 defmulti
正在缓存分派函数。以下是修改后的代码,以说明问题:
(defn who-is-it [person] (:name person))
(spyx (who-is-it {:name :joe}))
(defmulti do-something who-is-it)
(defmethod do-something :homer [person] :doh)
(defmethod do-something :bill [person] :oh-no)
(defmethod do-something :ted [person] :excellent)
(spyx (do-something {:name :homer}))
(spyx (do-something {:name :bill}))
(defn who-is-it [arg] :ted)
(spyx (who-is-it :wilma))
(spyx (do-something {:name :betty}))
带有结果:
:reloading (tst.clj.core)
(who-is-it {:name :joe}) => :joe
(do-something {:name :homer}) => :doh
(do-something {:name :bill}) => :oh-no
(who-is-it :wilma) => :ted
:error-while-loading tst.clj.core
Error refreshing environment: java.lang.IllegalArgumentException: No method in multimethod 'do-something' for dispatch value: :betty, compiling:(tst/clj/core.clj:22:27)
看起来您可能需要重新初始化REPL以重新定义分派函数。 即使重复所有操作,do-something
对我也没有被覆盖:
(defmulti do-something who-is-it)
(defmethod do-something :homer [person] :doh)
(defmethod do-something :bill [person] :oh-no)
(defmethod do-something :ted [person] :excellent)
(spyx (do-something {:name :betty}))
Error refreshing environment: java.lang.IllegalArgumentException: No method in multimethod 'do-something' for dispatch value: :betty, compiling:(tst/clj/core.clj:30:1)
在这里,我们看到了一个新的会话,它展示了预期的行为:
(defn who-is-it [person] (:name person))
(spyx (who-is-it {:name :joe}))
(defn who-is-it [arg] :ted)
(spyx (who-is-it :wilma))
(defmulti do-something who-is-it)
(defmethod do-something :homer [person] :doh)
(defmethod do-something :bill [person] :oh-no)
(defmethod do-something :ted [person] :excellent)
(dotest
(spyx (do-something {:name :betty})))
(do-something {:name :betty}) => :excellent
更新
我尝试了Rumid描述的ns-unmap
技术并且也可以工作。我注意到您需要重新发出defmulti
和所有defmethod
语句:都。
(ns-unmap *ns* 'do-something)
(defmulti do-something who-is-it)
(defmethod do-something :homer [person] :doh)
(defmethod do-something :bill [person] :oh-no)
(defmethod do-something :ted [person] :excellent)
(dotest
(newline)
(spyx (do-something {:name :betty})))
ns-unmap
放在文件的顶部用于实验目的,当我把文件发送给nREPL时,更改会如预期一样生效。 - Kris