This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-02-06
Channels
- # adventofcode (1)
- # aleph (9)
- # announcements (22)
- # beginners (59)
- # boot (8)
- # calva (1)
- # cljdoc (7)
- # cljs-dev (10)
- # cljsrn (9)
- # clojars (10)
- # clojure (23)
- # clojure-dev (6)
- # clojure-europe (3)
- # clojure-italy (26)
- # clojure-nl (3)
- # clojure-seattle (1)
- # clojure-spec (46)
- # clojure-uk (85)
- # clojurescript (97)
- # core-async (13)
- # cursive (3)
- # data-science (10)
- # datomic (156)
- # duct (34)
- # emacs (37)
- # figwheel (3)
- # figwheel-main (9)
- # fulcro (59)
- # hyperfiddle (4)
- # immutant (1)
- # jackdaw (3)
- # jobs (1)
- # off-topic (112)
- # parinfer (1)
- # qlkit (2)
- # re-frame (1)
- # reagent (35)
- # ring-swagger (2)
- # shadow-cljs (104)
- # spacemacs (9)
- # speculative (12)
- # tools-deps (30)
- # yada (10)
I haven’t created an official release yet — currently trialing it out. Any comments greatfully received.
@rickmoynihan Looks pretty reasonable, and a good tool for stubbing out multimethods. When you're happy with it, submit it to the Clojure toolbox and I'll add it to the directory 🙂
my main issue with it, which I still need to investigate more fully is how it interacts with ig/load-namespaces
I haven’t fully debugged it yet… but it looked very much like if the method bodies aren’t loaded before you with-redef-methods
it - then you’d get a classcast exception
I see what you mean... If a defmethod
is hit for an overridden multimethod.
so I had to resort to loading the namespaces by hand, before redef-ing them. I’m guessing because load-namespaces
replaces the var
I don't think load-namespaces
replaces the var... since the var would be integrant.core/init-key
, which should already be loaded, because load-namespaces
is in integrant.core
.
yeah you’re right — it’s the internals of the defmethod though
But what it will do is call defmethod
on init-key
, so it expects init-key
to be a multimethod.
Okay, so defmethod
expects a clojure.lang.MultiFn
...
not sure quite what you’re saying… what I’m saying is that the internals of a multi are mutable state too
that was the ClassCastException
not got a repl open just now
was meaning to isolate the causes in a minimal harness
ahh right enough there’s a :tag
hint
So I think I'd copy the multimethod... like, (clojure.lang.MultiFn. (.name m) (.dispatchFn m) (.defaultDispatchVal m) (.hierarchy m))
Since they're all public members: https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/MultiFn.java
yeah was just thinking something like that would be the solution
thanks
And then override the copied MultiFn by adding your own .addMethod
.
really? I avoid mutating anything just now
Maybe set up a default dispatch that goes back to the original?
does that already
Even though you'd be mutating the MultiFn clone, you'd be throwing away the clone afterwards.
Like:
(defn clone-multimethod [m]
(let [m' (clojure.lang.MultiFn. (.name m) ...)]
(doseq [[k f] (methods m)]
(.addMethod m' k f))
m'))
Or just add a default dispatch going back to the original, maybe:
(defn clone-multimethod [m]
(let [m' (clojure.lang.MultiFn. (.name m) ...)]
(.addMethod m' (.defaultDispatchVal m) m)
m'))
Although... I guess you'd want a proxy of the MultiFn, so you could ensure that .addMethod
doesn't override the stuff you've overridden yourself.
Perhaps at that point it's better to go back to Java and inherit a new class from the old... unless proxy does that for us. I can't remember if it keeps inherited methods or not.
sorry had to rush off out… will have a look and think