2011-12-19 50 views
2

開始編輯:爲什麼Clojure defmulti調度函數接收0個參數?

Mea Culpa!我道歉。

我在Clojure 1.2.1的cake repl中運行了它,它老實說沒有工作。現在它退出蛋糕repl和蛋糕編譯後,它也在1.3.0工作。

末編輯:

在下面:我的調度功能被傳遞零個ARGS,但我想不出爲什麼。我已經測試了調度功能,並且它完成了它應有的功能。我將不勝感激任何建議。

(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 
+0

將您的代碼複製並粘貼到乾淨的repl中不會產生您報告的錯誤。它運行並返回值2.0。 – 2011-12-19 17:45:01

+0

謝謝。我試過了,並得到了錯誤,所以也許這是Clojure版本相關?再次嘗試Clojure 1.3,它的工作。 – octopusgrabbus 2011-12-19 17:46:04

+0

在1.2.1 repl嘗試,工作正常 – skuro 2011-12-19 18:01:43

回答

10

的問題或許涉及到的defmulti無證defonce般的行爲。

如果您重新加載包含(defmulti foo ...)表單的名稱空間,則不會更新該defmulti。這通常意味着調度函數不會被更新,但是所有的方法實現(在相同的命名空間中)都會被更新。 (defmulti foo ...)什麼都不做,如果foo變種已經被綁定到一個值。

要在REPL解決此問題,刪除多方法VAR (ns-unmap 'the.ns 'the-multimethod),然後重新加載命名空間(require 'the.ns :reload)

爲了避免這個問題,你可以定義調度功能及其變種,並分別傳遞給defmulti這樣的:

(defn foo-dispatch [...] 
    ...) 

(defmulti foo #'foo-dispatch) 

當代碼看起來像這樣它足以重新加載命名空間,如果你進行了更改foo-dispatch

+0

感謝您的回答。這是一個很大的幫助。 – octopusgrabbus 2011-12-19 18:46:44

相關問題