Skip to content

Instantly share code, notes, and snippets.

@camsaul
Created May 21, 2021 19:55
Show Gist options
  • Save camsaul/4cec56ccd8febdf3bbfa3cf6aba68124 to your computer and use it in GitHub Desktop.
Save camsaul/4cec56ccd8febdf3bbfa3cf6aba68124 to your computer and use it in GitHub Desktop.
Clojure unprefer-method
(defmulti my-multimethod
keyword)
(derive ::x ::keyword)
(derive ::y ::keyword)
(defmethod my-multimethod ::x
[_]
::x)
(defmethod my-multimethod ::y
[_]
::x)
(derive ::z ::x)
(derive ::z ::y)
(my-multimethod ::z)
;; -> ERROR
(prefer-method my-multimethod ::x ::y)
(my-multimethod ::z)
;; -> ::x
(defn reset-cache [^clojure.lang.MultiFn multimethod]
(let [method (doto (.getDeclaredMethod clojure.lang.MultiFn "resetCache" ^"[Ljava.lang.Class;" (into-array Class []))
(.setAccessible true))]
(.invoke method multimethod ^"[Ljava.lang.Object;" (into-array Object []))))
(defn prefer-table [^clojure.lang.MultiFn multimethod]
(.getPreferTable multimethod))
(defn set-prefer-table! [^clojure.lang.MultiFn multimethod table]
(let [^java.lang.reflect.Field field (doto (.getDeclaredField clojure.lang.MultiFn "preferTable")
(.setAccessible true))]
(.set field multimethod table))
(reset-cache multimethod))
(defn unprefer-method [multimethod dispatch-val-x dispatch-val-y]
(let [table (update (prefer-table multimethod) dispatch-val-x disj dispatch-val-y)]
(set-prefer-table! multimethod table)))
(unprefer-method my-multimethod ::x ::y)
(my-multimethod ::z)
;; -> ERROR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment