diff options
author | Rich Hickey <richhickey@gmail.com> | 2009-01-21 00:27:43 +0000 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2009-01-21 00:27:43 +0000 |
commit | 5d0ac342b80b5f60b9d2e9986c0c601f6cba0674 (patch) | |
tree | de9050ca1796d021c1ab1d4d04fc6c95f50f8074 /src | |
parent | 06d3b59c23ef90c9410470652ed6fc408d360716 (diff) |
added methods/prefers for multimethod reflection
Diffstat (limited to 'src')
-rw-r--r-- | src/clj/clojure/core.clj | 8 | ||||
-rw-r--r-- | src/jvm/clojure/lang/MultiFn.java | 24 |
2 files changed, 23 insertions, 9 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index 1b0d1484..1285dd2c 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -1026,6 +1026,14 @@ [multifn dispatch-val-x dispatch-val-y] (. multifn preferMethod dispatch-val-x dispatch-val-y)) +(defn methods + "Given a multimethod, returns a map of dispatch values -> dispatch fns" + [multifn] (.getMethodTable multifn)) + +(defn prefers + "Given a multimethod, returns a map of preferred value -> set of other values" + [multifn] (.getPreferTable multifn)) + ;;;;;;;;; var stuff (defmacro #^{:private true} assert-args [fnname & pairs] diff --git a/src/jvm/clojure/lang/MultiFn.java b/src/jvm/clojure/lang/MultiFn.java index ee007efc..bb818da4 100644 --- a/src/jvm/clojure/lang/MultiFn.java +++ b/src/jvm/clojure/lang/MultiFn.java @@ -13,7 +13,6 @@ package clojure.lang; import java.util.Map; -import java.util.Collection; public class MultiFn extends AFn{ final public IFn dispatchFn; @@ -33,19 +32,19 @@ public MultiFn(IFn dispatchFn, Object defaultDispatchVal) throws Exception{ this.dispatchFn = dispatchFn; this.defaultDispatchVal = defaultDispatchVal; this.methodTable = PersistentHashMap.EMPTY; - this.methodCache = methodTable; + this.methodCache = getMethodTable(); this.preferTable = PersistentHashMap.EMPTY; cachedHierarchy = null; } synchronized public MultiFn addMethod(Object dispatchVal, IFn method) throws Exception{ - methodTable = methodTable.assoc(dispatchVal, method); + methodTable = getMethodTable().assoc(dispatchVal, method); resetCache(); return this; } synchronized public MultiFn removeMethod(Object dispatchVal) throws Exception{ - methodTable = methodTable.without(dispatchVal); + methodTable = getMethodTable().without(dispatchVal); resetCache(); return this; } @@ -54,7 +53,7 @@ synchronized public MultiFn preferMethod(Object dispatchValX, Object dispatchVal if(prefers(dispatchValY, dispatchValX)) throw new IllegalStateException( String.format("Preference conflict: %s is already preferred to %s", dispatchValY, dispatchValX)); - preferTable = preferTable.assoc(dispatchValX, RT.conj((IPersistentCollection) RT.get(preferTable, + preferTable = getPreferTable().assoc(dispatchValX, RT.conj((IPersistentCollection) RT.get(getPreferTable(), dispatchValX, PersistentHashSet.EMPTY), dispatchValY)); @@ -63,7 +62,7 @@ synchronized public MultiFn preferMethod(Object dispatchValX, Object dispatchVal } private boolean prefers(Object x, Object y) throws Exception{ - IPersistentSet xprefs = (IPersistentSet) preferTable.valAt(x); + IPersistentSet xprefs = (IPersistentSet) getPreferTable().valAt(x); if(xprefs != null && xprefs.contains(y)) return true; for(ISeq ps = RT.seq(parents.invoke(y)); ps != null; ps = ps.rest()) @@ -88,7 +87,7 @@ private boolean dominates(Object x, Object y) throws Exception{ } private IPersistentMap resetCache(){ - methodCache = methodTable; + methodCache = getMethodTable(); cachedHierarchy = hierarchy.get(); return methodCache; } @@ -102,7 +101,7 @@ synchronized private IFn getFn(Object dispatchVal) throws Exception{ targetFn = findAndCacheBestMethod(dispatchVal); if(targetFn != null) return targetFn; - targetFn = (IFn) methodTable.valAt(defaultDispatchVal); + targetFn = (IFn) getMethodTable().valAt(defaultDispatchVal); if(targetFn == null) throw new IllegalArgumentException(String.format("No method for dispatch value: %s", dispatchVal)); return targetFn; @@ -110,7 +109,7 @@ synchronized private IFn getFn(Object dispatchVal) throws Exception{ private IFn findAndCacheBestMethod(Object dispatchVal) throws Exception{ Map.Entry bestEntry = null; - for(Object o : methodTable) + for(Object o : getMethodTable()) { Map.Entry e = (Map.Entry) o; if(isA(dispatchVal, e.getKey())) @@ -289,4 +288,11 @@ public Object invoke(Object arg1, Object arg2, Object arg3, Object arg4, Object arg15, arg16, arg17, arg18, arg19, arg20, args); } + public IPersistentMap getMethodTable() { + return methodTable; + } + + public IPersistentMap getPreferTable() { + return preferTable; + } } |