A common way to develop code (don’t blame the messenger) is to start the application watch for the logged errors, make changes and then restart the application again, looking for more logged errors.
That’s not how it’s done in the world of Clojure, not just because it’s bad, but because the process of starting any Clojure program is horribly slow. Instead, in Clojure normally you start the application and then connect with a terminal window running a Clojure REPL. For example, if you are running a Luminus server, when you start it, it will tell you what port the server is listening for REPL connections on.
So, how do you connect to a running application with a REPL?
I use ‘lein’ for my dependency tool, so I find it easiest to connect using ‘lein repl’. You do have to provide the host and port to connect to, though.
1 |
lein repl :connect localhost:7000 |
This gets you logged into your running app. That’s nice. That’s not enough.
If you have a ‘user’ namespace like Luminus does by default, you can use the functions defined in it now. However, for any real debug work, you need to load and switch to the namespaces you are developing in.
1 2 |
(require 'my-web-app.db.user-db) (in-ns 'my-web-app.db.user-db) |
Now you have access to the namespace you are working in, if you replaced
1 |
my-web-app.db.user-db |
with your namespace, that is. Go ahead and invoke any functions defined in your namespace.
“One more thing,” as Uncle would say.
If you’re developing new code, your loaded files will not match your source on the drive for very long. Simple, specify the namespace as needing reloading. Ether of the following will work.
1 |
(require 'my-web-app.db.user-db :reload) |
or, better yet, …
1 |
(require 'my-web-app.db.user-db :reload-all) |
Usually :reload-all works best, but in rare situations, this may take longer than :reload .
Now, the latest version of your namespace from disk should be in your running application.