Refresh breaks when changing priority of conflicting methods in `prefer-method`


Try defining a record that implements the clojure.lang.IDeref protocol. Create an instance, then try to print it, and you'll get an exception like so:

java.lang.IllegalArgumentException: Multiple methods in multimethod 'print-method' match dispatch value: class <record-class-name> -> interface clojure.lang.IPersistentMap and interface clojure.lang.IDeref, and neither is preferred

The solution to this is to include this line after the defrecord form:

(prefer-method print-method clojure.lang.IDeref clojure.lang.IPersistentMap)

This is all fine so far. The problem is that if you change the preference and call (ctn/refresh), you get an exception:

Error refreshing environment: java.lang.IllegalStateException: Preference conflict in multimethod 'print-method': interface clojure.lang.IPersistentMap is already preferred to interface clojure.lang.IDeref, compiling<source-file.clj>:164:22)


Clojure 1.6, CTN 0.2.5.


Stuart Sierra
September 7, 2014, 4:37 PM

Added warning to README in [commit 57e5658c8d9154711979019d85b279ad5f6898c9](

Stuart Sierra
September 5, 2014, 8:32 PM

Will add a note in README

September 5, 2014, 8:05 PM

Comment made by: jeffterrell

Fair enough. Thanks for looking into it.

Is this limitation worth documenting somewhere? Perhaps either in the API docs or in the c.t.n README?

Stuart Sierra
September 4, 2014, 10:18 PM

This is because prefer-method is a global side-effect at the top-level of a namespace.

The only way to work around this would be to call remove-method before reloading the namespace. Knowing to do that would require deep analysis far outside the scope of tools.namespace, but it can be done in application-specific code in a wrapper around refresh.

Your pinned fields
Click on the next to a field label to start pinning.


Stuart Sierra