在cljs.core/-prefer-method中的冲突测试似乎是反向的,这会导致在合理地多次使用prefer-method时出错(例如,在repl中重新加载代码)。
以下是问题的最小化再现。虽然这里的层次结构和方法是微不足道的,但解决真实歧义的prefer-method也会发生相同的问题。请注意,消息表明相对于prefer-method的文档,首选项被反转。(我们希望在这里首选:a,但消息表明相反。)
(def tmph (make-hierarchy))
(defmulti fooz (fn [a b] (keyword b)) :hierarchy #'tmph)
(defmethod fooz :a [a b] a)
(defmethod fooz :b [a b] b)
(prefer-method fooz :a :b)
;=> {:parents {}, :descendants {}, :ancestors {}}
(prefer-method fooz :a :b)
;;
;; Execution error (Error) at (<cljs repl>:1).
;; Preference conflict in multimethod 'cljs.user/fooz': :b is already preferred to :a
;; :repl/exception!
使用ClojureScript 1.10.914在干净的安装中运行clj -M -m cljs.main --repl-env node
,并使用从master构建的uberjar(当时)执行。
问题似乎在于prefer*的第一个两个参数在(Line 11356 core.cljs在MultiFn的定义中)中被反转了。这里的调用是使x优先于y,应该是连贯的。
(when (prefers* dispatch-val-x dispatch-val-y prefer-table)
(throw (js/Error. (str "Preference conflict in multimethod '" name "': " dispatch-val-y
" is already preferred to " dispatch-val-x))))
(在这里的调用是为了使x比y更优先,这应该是连贯的)
谢谢!