4

I'm not sure if this is expected or a bug, but after running (clojure.tools.namespace.repl/refresh-all) the clojure.repl namespace is lost.

nREPL server started on port 61579 on host 127.0.0.1 nrepl://127.0.0.1:61579
REPL-y 0.3.5, nREPL 0.2.7
Clojure 1.6.0

testbed.core=> (doc map)
-------------------------
clojure.core/map
([f coll] [f c1 c2] [f c1 c2 c3] [f c1 c2 c3 & colls])
Returns a lazy...
nil
testbed.core=> (require 'clojure.tools.namespace.repl)
nil
testbed.core=> (clojure.tools.namespace.repl/refresh-all)
:reloading (testbed.core testbed.core-test)
:ok
testbed.core=> (doc map)

CompilerException java.lang.RuntimeException: Unable to resolve symbol: doc in this context, compiling:(/private/var/folders/xs/jbvb_r6j07q8xtclwlcbm21h0000gn/T/form-init6764593924445976503.clj:1:1)
testbed.core=>

My project.clj is very simple:

(defproject testbed "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.6.0"]]
  :main ^:skip-aot testbed.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all}
             :dev {:dependencies [[org.clojure/tools.namespace "0.2.10"]]}})

Is there a simple way to avoid this? Particular while running Emacs/CIDER?

drt
  • 888
  • 1
  • 8
  • 19

2 Answers2

5

I remember having this issue. Although it's been a while, I recall getting around this by setting up my lein project to start the repl in namespace user and import the other namespaces - rather than starting out in the project namespace (defined by :main).

So I added :repl-options {:init-ns user} to my project.clj and also created a project user.clj - that ensures that clojure.repl functions I need are always available - as described in Stuart Sierra's post "My Clojure Workflow, Reloaded"

Session:

user=> (doc +)
-------------------------
clojure.core/+
([] [x] [x y] [x y & more])
  Returns the sum of nums. (+) returns 0. Does not auto-promote
  longs, will throw on overflow. See also: +'
nil

user=> (clojure.tools.namespace.repl/refresh-all)
(...namespaces...)

user=> (doc +)
-------------------------
clojure.core/+
([] [x] [x y] [x y & more])
  Returns the sum of nums. (+) returns 0. Does not auto-promote
  longs, will throw on overflow. See also: +'
nil

This is a work-around and not a real fix or explanation of the behavior. Another approach could be to ensure

noahlz
  • 10,202
  • 7
  • 56
  • 75
3

clojure.tools.namespace.repl/refresh-all works by destroying the current in memory version of a namespace before loading the new one. Since the doc function is inserted by the REPL on startup and not defined in your source file, it is lost on reload.

You can use the functions disable-unload! and disable-reload! in clojure.tools.namespace.repl to prevent refresh from automatically un/reloading namespaces. nREPL inserts helper functions like doc in the initial namespace which is by default the main namespace of you application. You can make sure these functions are inserted elsewhere by setting an alternative initial namespace in your Leiningen profile.

I also recommend creating an actual source file for the namespace that contains helper functions for use at the REPL. You can find a description on how to do so in one of my other answers.

An example user profile setup can found on my Github.

Community
  • 1
  • 1
Dirk Geurs
  • 2,392
  • 19
  • 24