Почему функция отправки Clomure defmulti получает 0 аргументов? - PullRequest
2 голосов
/ 19 декабря 2011

Начало редактирования:

Меа Калпа!Я прошу прощения.

Я выполнял это в репорте тортов на Clojure 1.2.1, и, честно говоря, это не сработало.Теперь это происходит после выхода из торта repl и компиляции торта, а также работает на 1.3.0.

End Edit:

В следующем: моей функции отправки передается ноль аргументов, ноЯ не могу понять, почему.Я проверил функцию отправки, и она делает то, что должна.Буду признателен за любые предложения.

(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

1 Ответ

11 голосов
/ 19 декабря 2011

Возможно, проблема связана с недокументированным defonce -подобным поведением defmulti.

Если вы перезагрузите пространство имен, содержащее форму (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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...