diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-04-09 19:32:49 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-04-09 19:32:49 +0000 |
commit | 653d6ee1fc4ffe7e60487a401298832faac18b48 (patch) | |
tree | c6afa8f5693bc21b2e17f6956c22c3a5263dd14d | |
parent | d5ed6f9dfc014f9ff0e73b48e49dd7063b2c3096 (diff) |
pass defmethod names to MultiFns and use in error reporting
-rw-r--r-- | src/clj/clojure/core.clj | 2 | ||||
-rw-r--r-- | src/jvm/clojure/lang/MultiFn.java | 14 |
2 files changed, 10 insertions, 6 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 934dbe89..ac7d94eb 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -1064,7 +1064,7 @@ default (get options :default :default) hierarchy (get options :hierarchy #'global-hierarchy)] `(def ~(with-meta mm-name m) - (new clojure.lang.MultiFn ~dispatch-fn ~default ~hierarchy))))) + (new clojure.lang.MultiFn ~(name mm-name) ~dispatch-fn ~default ~hierarchy))))) (defmacro defmethod "Creates and installs a new method of multimethod associated with dispatch-value. " diff --git a/src/jvm/clojure/lang/MultiFn.java b/src/jvm/clojure/lang/MultiFn.java index 1efa84b6..28a49c01 100644 --- a/src/jvm/clojure/lang/MultiFn.java +++ b/src/jvm/clojure/lang/MultiFn.java @@ -18,6 +18,7 @@ public class MultiFn extends AFn{ final public IFn dispatchFn; final public Object defaultDispatchVal; final public IRef hierarchy; +final String name; IPersistentMap methodTable; IPersistentMap preferTable; IPersistentMap methodCache; @@ -28,7 +29,8 @@ static final Var dissoc = RT.var("clojure.core", "dissoc"); static final Var isa = RT.var("clojure.core", "isa?"); static final Var parents = RT.var("clojure.core", "parents"); -public MultiFn(IFn dispatchFn, Object defaultDispatchVal, IRef hierarchy) throws Exception{ +public MultiFn(String name, IFn dispatchFn, Object defaultDispatchVal, IRef hierarchy) throws Exception{ + this.name = name; this.dispatchFn = dispatchFn; this.defaultDispatchVal = defaultDispatchVal; this.methodTable = PersistentHashMap.EMPTY; @@ -53,7 +55,8 @@ synchronized public MultiFn removeMethod(Object dispatchVal) throws Exception{ synchronized public MultiFn preferMethod(Object dispatchValX, Object dispatchValY) throws Exception{ if(prefers(dispatchValY, dispatchValX)) throw new IllegalStateException( - String.format("Preference conflict: %s is already preferred to %s", dispatchValY, dispatchValX)); + String.format("Preference conflict in multimethod '%s': %s is already preferred to %s", + name, dispatchValY, dispatchValX)); preferTable = getPreferTable().assoc(dispatchValX, RT.conj((IPersistentCollection) RT.get(getPreferTable(), dispatchValX, PersistentHashSet.EMPTY), @@ -109,7 +112,8 @@ synchronized public IFn getMethod(Object dispatchVal) throws Exception{ private IFn getFn(Object dispatchVal) throws Exception{ IFn targetFn = getMethod(dispatchVal); if(targetFn == null) - throw new IllegalArgumentException(String.format("No method for dispatch value: %s", dispatchVal)); + throw new IllegalArgumentException(String.format("No method in multimethod '%s' for dispatch value: %s", + name, dispatchVal)); return targetFn; } @@ -125,8 +129,8 @@ private IFn findAndCacheBestMethod(Object dispatchVal) throws Exception{ if(!dominates(bestEntry.getKey(), e.getKey())) throw new IllegalArgumentException( String.format( - "Multiple methods match dispatch value: %s -> %s and %s, and neither is preferred", - dispatchVal, e.getKey(), bestEntry.getKey())); + "Multiple methods in multimethod '%s' match dispatch value: %s -> %s and %s, and neither is preferred", + name, dispatchVal, e.getKey(), bestEntry.getKey())); } } if(bestEntry == null) |