I am writing a multimethod in the REPL, functions can be redefined just fine, but if I redefine the dispatch function of a multi method it seems not to use the newly refined function:
;; 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
How do I get the mult imethod to reflect changes to the dispatch function, resolve-it
?
There is a simple technique that allows re-defining the dispatch function of the multimethod. The idea is to pass the var that holds the dispatch function to defmulti
, not the function itself. Note the #'resolve-it
in defmulti
instead of just resolve-it
. Thus the var is de-referenced at runtime, not just at compile time.
(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!!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With