Tips for reloaded workflow
metametadata opened this issue · comments
It would be great to have a section about the reloaded REPL workflow in the README because it's one of the main reasons one would want to use Component-like pattern.
In particular, it would be interesting to see if there's a reliable way of reloading multimethods. I've stumbled upon a problem of old definition of method still working after it was removed from ns and reset
-ing. To solve this particular problem I've ended with this in a sample project:
(ns user
"Namespace to support hacking at the REPL.
Usage:
o (reset) - [re]run the app.
o In case REPL fails after syntax error, call (refresh) and try again.
"
(:require [my-app.core :as core]
[integrant.core :as ig]
[clojure.tools.namespace.repl :refer [refresh refresh-all]]
[clojure.repl :refer :all]
[clojure.pprint :refer :all]))
(println "Hi dev!")
(def system (atom nil))
(defn -start
[]
(reset! system (ig/init core/config)))
(defn -stop
[]
(swap! system (fn [s] (when s (ig/halt! s)))))
(defn reset
[]
(-stop)
; this will force reloading of the methods
(remove-all-methods ig/init-key)
(remove-all-methods ig/halt-key!)
; etc.
; refresh-all is used instead of refresh because we've just removed all the methods and want to find all the definitions
(refresh-all :after 'user/-start))
But I'm not sure if refresh-all
is going to be fast enough in bigger projects.
Rather than including it in the README, I was going to write an "integrant-repl" project that mimics my existing "reloaded.repl" project.
With regard to reloading multimethods, it hasn't been something I've thought about a lot, yet. One possibility is to create an improved defmethod
that attaches some namespace metadata to the function before attaching it to the multimethod.
I've created an Integrant-REPL project, now.