Begin Edit:
Mea Culpa! I apologize.
I was running this in the cake repl at Clojure 1.2.1, and it honestly did not work. Now it does after exiting cake repl and a cake compile, and it also works at 1.3.0.
End Edit:
In the following: my dispatch function is being passed zero args, but I cannot figure out why. I’ve tested the dispatch function, and it does what it is supposed to. I would appreciate any suggestions.
(defrecord AcctInfo [acct-type int-val cur-bal])
(def acct-info (AcctInfo. \C 0.02 100.00))
ba1-app=> acct-info
ba1_app.AcctInfo{:acct-type \C, :int-val 0.02, :cur-bal 100.0}
(defn get-int-calc-tag [acct-type]
(cond (= acct-type \C) :checking
(= acct-type \S) :savings
(= acct-type \M) :moneym
:else :unknown))
(defmulti calc-int (fn [acct-info] (get-int-calc-tag (:acct-type acct-info))))
(defmethod calc-int :checking [acct-info] (* (:cur-bal acct-info) (:int-val acct-info)))
ba1-app=> (get-int-calc-tag (:acct-type acct-info))
:checking
ba1-app=> (calc-int acct-info)
java.lang.IllegalArgumentException: Wrong number of args (0) passed to: ba1-app$get-int-calc-tag
The problem could perhaps be related to the undocumented
defonce-like behavior ofdefmulti.If you reload a namespace that contains a
(defmulti foo ...)form then thatdefmultiwon’t be updated. This often means that the dispatch function will not be updated but all method implementations (in the same namespace) will. (defmulti foo ...)does nothing if thefoovar is already bound to a value.To fix this in a REPL, remove the multimethod var
(ns-unmap 'the.ns 'the-multimethod)and then reload the namespace(require 'the.ns :reload).To prevent this problem you can define the dispatch function separately and pass its var to
defmultilike this:When the code looks like this it’s enough to reload the namespace if you make a change to
foo-dispatch.