clojure - 如何在 Clojure REPL 中重新加载多方法

标签 clojure

我正在REPL中编写一个多方法,可以重新定义函数,但是如果我重新定义多方法的调度函数,它似乎不能使用新改进的函数:

;; simple fn to resolve defmethod to call, hardcoded to :do-it
(defn resolve-it [] :do-it)
(resolve-it) ;; :do-it, as expected

(defmulti do-something resolve-it)

(defmethod do-something :do-it [] (println "do-it"))
(defmethod do-something :oh-no [] (println "oh-no"))

(do-something) ;; "do-it", as expected

;; now change resolve-it
(defn resolve-it [] :oh-no)
(resolve-it) ;; :oh-no, as expected

(do-something) ;; "do-it", not as expected

(do-something) ;; "do-it", not expected

如何使用 mult 方法来反射(reflect)对调度函数 resolve-it 的更改?

最佳答案

有一种简单的技术可以重新定义多方法的调度函数。这个想法是将保存调度函数的 var 传递给 defmulti,而不是函数本身。请注意 defmulti 中的 #'resolve-it 而不仅仅是 resolve-it。因此,var 在运行时被取消引用,而不仅仅是在编译时。

(defn resolve-it [] :do-it)
(resolve-it) ;; :do-it, as expected

(defmulti do-something #'resolve-it)

(defmethod do-something :do-it [] (println "do-it"))
(defmethod do-something :oh-no [] (println "oh-no"))

(do-something) ;; "do-it", as expected

;; now change resolve-it
(defn resolve-it [] :oh-no)
(resolve-it) ;; :oh-no, as expected

(do-something) ;; "oh-no", expected!!

关于clojure - 如何在 Clojure REPL 中重新加载多方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44807442/

相关文章:

function - 在多个命名空间中使用记录

macros - 如何创建一个宏来在 clojure 中定义两个函数

Clojure,将多个序列连接成一个

emacs - Slime 在我的 Clojure repl 中抛出 "Variable binding depth exceeds max-specpdl-size"

Clojure - 这是原子的适当使用吗?

matlab - 在 clojure 中,如何将函数应用于 [大] 向量中的选定项目

clojure - 使用lazy-seq确定代码中StackOverflow的原因

clojure - 动态莱宁根 :profiles

syntax - 何时在 clojure require 中包含撇号?

clojure - 检查一个向量是否至少包含来自另一个向量的一个值