可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am not meaning cleaning up the text output of REPL; I mean cleaning up all evaluated results in REPL. During developing, repeatedly C-c C-q
and C-c M-j
is low efficiency.
UPDATE
There may be some bad debug behaviour of mine. I am not sure how other people develop progs with CIDER, but I really need the functionality mentioned above. I guess other developers also encounter same problems as mine.
For example, at the top of a clojure prog unit, I use declare
to declare a function foo
, which is used by another function bar
, and foo
is implemented after bar
. Then, I C-c C-k
, etc, and the prog goes well. Later, I removed the forward declaration of foo
occasionally. What does happen? The prog still goes well. REALLY? Then, I commit my whole job and terminate the CIDER REPL session happily.
Disaster on morning: Symbol foo
not found!
That's my story. So, nobody has ever encountered similar problems?
回答1:
Try the (refresh)
function in the clojure.tools.namespace.repl
namespace:
The refresh function will scan all the directories on the classpath for Clojure source files, read their ns declarations, build a graph of their dependencies, and load them in dependency order.
https://github.com/clojure/tools.namespace#reloading-code-usage
It doesn't seem to remove the vars declared in the user
namespace, which I've typed into the REPL, but it does:
...unload (remove) the namespaces that changed to clear out any old
definitions.
We generally add that plus a few other useful things to the user
namespace, so it's loaded into the REPL on startup:
(ns user
(:require [clojure.tools.namespace.repl :refer [refresh]]
[clojure.repl :refer [doc source]]
[clojure.pprint :refer [pprint pp]]
[midje.repl :as midje]
[clojure.stacktrace :as st]))
To keep that code separate from your main and test sources, put that in a file at <project root>/dev/user.clj
, then add the following to your lein project.clj
file:
:profiles {:dev {:source-paths ["dev"]}}
(p.s. although it's not the question you want answered, for those seeing this answer and wanting to clear the text in the Cider REPL, it's C-c M-o
(https://github.com/clojure-emacs/cider)
回答2:
Like others have already pointed out, the 'proper' solution is to use Stuart Sierra's component library.
But since you're running in CIDER, you can use C-c C-x
to run cider-refresh
, which will reload your project and thereby recreate your initial state.
回答3:
In EMACS when I works with Clojure in cider-mode, I use:
C-c M-o in the repl buffer
it is bound to cider-repl-clear-buffer
回答4:
If you're dealing with a large number of things which have state which you want to clear to have a clean developing environment you might consider doing one of the following:
1.) Reassess your design and see how much of that state is actually necessary. In many situations you might be using atoms, refs, or other stateful items unnecessarily and if you adopt a more functional approach, you won't find yourself needing to clear up your development environment as often.
Presuming legitimate reasons for using state:
2.) You can wipe out a namespace and all of it's contents by using the clojure function remove-ns
: e.g. for a namespace called user.fancy-namespace
you can clean the NS out by running (remove-ns 'user.fancy-namespace')
and then simply re-evaluating the namespace. This works well for cleaning up a single namespace, but if the stateful items you need cleaned are in other namespaces, it can get tedious to do this for every namespace involved.
3.) Stuart Sierra's component library was designed to manage components which involve state. Very useful for managing DB connections, memcache clients, etc, but will require a re-architecting of your project in order to make full use of it.
回答5:
As mentioned by others, it is only necessary to clear the repl if you have variables which are holding state information. For non-state carrying components, just reloading the source buffer (re-evaluating it) is sufficient.
One very interesting way to manage a workflow which does have components that track state is Stuart Seirra's component framework. See http://youtu.be/13cmHf_kt-Q
Another approach is to write your code using defonce rather than def, which will allow you to reload your source code without redefining state variables.
If on the other hand, you want to do this to clean up defn or defmacro definitions you don't need i.e. clean out 'polution' from your repl, then to be honest, I wouldn't bother. If nothing is calling a defn or macro, it really doesn't matter.