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

Description

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)

Environment

Clojure 1.6, CTN 0.2.5.

Activity

Show:
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.

import
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 5, 2014, 8:32 PM

Will add a note in README

Stuart Sierra
September 7, 2014, 4:37 PM

Added warning to README in [commit 57e5658c8d9154711979019d85b279ad5f6898c9](https://github.com/clojure/tools.namespace/commit/57e5658c8d9154711979019d85b279ad5f6898c9).

Declined

Assignee

Stuart Sierra

Reporter

import

Labels

None

Approval

None

Patch

None

Priority

Minor