Skip to content

Commit

Permalink
gave defmulti defonce-like semantics, i.e. calling again won't trash …
Browse files Browse the repository at this point in the history
…multifn object, to help in reload scenarios

added remove-all-methods for multifns
  • Loading branch information
richhickey committed Apr 20, 2010
1 parent e660e46 commit 1b8d500
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 7 deletions.
11 changes: 9 additions & 2 deletions src/clj/clojure/core.clj
Expand Up @@ -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]
Expand Down
5 changes: 0 additions & 5 deletions src/clj/clojure/core_print.clj
Expand Up @@ -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]
Expand Down
6 changes: 6 additions & 0 deletions src/jvm/clojure/lang/MultiFn.java
Expand Up @@ -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();
Expand Down

0 comments on commit 1b8d500

Please sign in to comment.