tools.namespace

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

Details

  • Type: Defect Defect
  • Status: Closed Closed
  • Priority: Minor Minor
  • Resolution: Declined
  • Affects Version/s: None
  • Fix Version/s: None
  • Component/s: None
  • Labels:
  • Environment:
    Clojure 1.6, CTN 0.2.5.

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)

Activity

Hide
Stuart Sierra added a comment -

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.

Show
Stuart Sierra added a comment - 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.
Hide
Jeff Terrell added a comment -

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?

Show
Jeff Terrell added a comment - 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?
Hide
Stuart Sierra added a comment -

Will add a note in README

Show
Stuart Sierra added a comment - Will add a note in README
Hide
Stuart Sierra added a comment -

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

Show
Stuart Sierra added a comment - Added warning to README in [commit 57e5658c8d9154711979019d85b279ad5f6898c9](https://github.com/clojure/tools.namespace/commit/57e5658c8d9154711979019d85b279ad5f6898c9).

People

Vote (0)
Watch (1)

Dates

  • Created:
    Updated:
    Resolved: