diff options
author | Rich Hickey <richhickey@gmail.com> | 2010-04-20 10:55:43 -0400 |
---|---|---|
committer | Rich Hickey <richhickey@gmail.com> | 2010-04-20 10:55:43 -0400 |
commit | 1b8d5001ba094053b24c55829994785be422cfbf (patch) | |
tree | 6b0d187262292e5ece9ed22b6efc13bc9a7716b4 | |
parent | e660e467789ccc8e9922948b3498939e0239fc7c (diff) |
gave defmulti defonce-like semantics, i.e. calling again won't trash multifn object, to help in reload scenarios
added remove-all-methods for multifns
-rw-r--r-- | src/clj/clojure/core.clj | 11 | ||||
-rw-r--r-- | src/clj/clojure/core_print.clj | 5 | ||||
-rw-r--r-- | src/jvm/clojure/lang/MultiFn.java | 6 |
3 files changed, 15 insertions, 7 deletions
diff --git a/src/clj/clojure/core.clj b/src/clj/clojure/core.clj index cb2f1d2b..ee3371fc 100644 --- a/src/clj/clojure/core.clj +++ b/src/clj/clojure/core.clj @@ -1189,14 +1189,21 @@ (let [options (apply hash-map options) default (get options :default :default) hierarchy (get options :hierarchy #'global-hierarchy)] - `(def ~(with-meta mm-name m) - (new clojure.lang.MultiFn ~(name mm-name) ~dispatch-fn ~default ~hierarchy))))) + `(let [v# (def ~mm-name)] + (when-not (and (.hasRoot v#) (instance? clojure.lang.MultiFn (deref v#))) + (def ~(with-meta mm-name m) + (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. " [multifn dispatch-val & fn-tail] `(. ~(with-meta multifn {:tag 'clojure.lang.MultiFn}) addMethod ~dispatch-val (fn ~@fn-tail))) +(defn remove-all-methods + "Removes all of the methods of multimethod." + [#^clojure.lang.MultiFn multifn] + (.reset multifn)) + (defn remove-method "Removes the method of multimethod associated with dispatch-value." [#^clojure.lang.MultiFn multifn dispatch-val] diff --git a/src/clj/clojure/core_print.clj b/src/clj/clojure/core_print.clj index 0ab1ee52..c0719711 100644 --- a/src/clj/clojure/core_print.clj +++ b/src/clj/clojure/core_print.clj @@ -137,16 +137,11 @@ (defmethod print-dup clojure.lang.ISeq [o w] (print-method o w)) (defmethod print-dup clojure.lang.IPersistentList [o w] (print-method o w)) -(prefer-method print-method clojure.lang.IPersistentList clojure.lang.ISeq) -(prefer-method print-dup clojure.lang.IPersistentList clojure.lang.ISeq) (prefer-method print-method clojure.lang.ISeq clojure.lang.IPersistentCollection) (prefer-method print-dup clojure.lang.ISeq clojure.lang.IPersistentCollection) (prefer-method print-method clojure.lang.ISeq java.util.Collection) (prefer-method print-dup clojure.lang.ISeq java.util.Collection) -(defmethod print-method clojure.lang.IPersistentList [o, #^Writer w] - (print-meta o w) - (print-sequential "(" print-method " " ")" o w)) (defmethod print-dup java.util.Collection [o, #^Writer w] diff --git a/src/jvm/clojure/lang/MultiFn.java b/src/jvm/clojure/lang/MultiFn.java index 28a49c01..62f48329 100644 --- a/src/jvm/clojure/lang/MultiFn.java +++ b/src/jvm/clojure/lang/MultiFn.java @@ -40,6 +40,12 @@ public MultiFn(String name, IFn dispatchFn, Object defaultDispatchVal, IRef hier cachedHierarchy = null; } +synchronized public MultiFn reset(){ + methodTable = methodCache = preferTable = PersistentHashMap.EMPTY; + cachedHierarchy = null; + return this; +} + synchronized public MultiFn addMethod(Object dispatchVal, IFn method) throws Exception{ methodTable = getMethodTable().assoc(dispatchVal, method); resetCache(); |