I'm learning Clojure with 'Clojure for the Brave and True' book and use emacs, cider and leiningen. I've created a project.
lein new app the-divine-cheese-code
Then I've added to source files to the project.
the-divine-cheese-code\src\the_divine_cheese_code\core.clj the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj
In 'core.clj' I refer to the 'svg.clj' namespace.
the-divine-cheese-code\src\the_divine_cheese_code\core.clj
(ns the-divine-cheese-code.core)
;; Ensure that the SVG code is evaluated
(require 'the-divine-cheese-code.visualization.svg)
;; Refer the namespace so that you don't have to use the
;; fully qualified name to reference svg functions
(refer 'the-divine-cheese-code.visualization.svg)
(def heists [{:location "Cologne, Germany"
:cheese-name "Archbishop Hildebold's Cheese Pretzel"
:lat 50.95
:lng 6.97}
{:location "Zurich, Switzerland"
:cheese-name "The Standard Emmental"
:lat 47.37
:lng 8.55}
{:location "Marseille, France"
:cheese-name "Le Fromage de Cosquer"
:lat 43.30
:lng 5.37}
{:location "Zurich, Switzerland"
:cheese-name "The Lesser Emmental"
:lat 47.37
:lng 8.55}
{:location "Vatican City"
:cheese-name "The Cheese of Turin"
:lat 41.90
:lng 12.45}])
(defn -main
[& args]
(println (points heists)))
the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj
(ns the-divine-cheese-code.visualization.svg)
(defn latlng->point
"Convert lat/lng map to comma-separated string"
[latlng]
(str (:lat latlng) "," (:lng latlng)))
(defn points
[locations]
(clojure.string/join " " (map latlng->point locations)))
Here is the project's entire dir structure.
the-divine-cheese-code
the-divine-cheese-code\.gitignore
the-divine-cheese-code\.hgignore
the-divine-cheese-code\.nrepl-port
the-divine-cheese-code\CHANGELOG.md
the-divine-cheese-code\doc
the-divine-cheese-code\doc\intro.md
the-divine-cheese-code\LICENSE
the-divine-cheese-code\project.clj
the-divine-cheese-code\README.md
the-divine-cheese-code\resources
the-divine-cheese-code\src
the-divine-cheese-code\src\the_divine_cheese_code
the-divine-cheese-code\src\the_divine_cheese_code\core.clj
the-divine-cheese-code\src\the_divine_cheese_code\visualization
the-divine-cheese-code\src\the_divine_cheese_code\visualization\svg.clj
the-divine-cheese-code\target
the-divine-cheese-code\target\default
the-divine-cheese-code\target\default\classes
the-divine-cheese-code\target\default\classes\META-INF
the-divine-cheese-code\target\default\classes\META-INF\maven
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code\the-divine-cheese-code
the-divine-cheese-code\target\default\classes\META-INF\maven\the-divine-cheese-code\the-divine-cheese-code\pom.properties
the-divine-cheese-code\target\default\repl-port
the-divine-cheese-code\target\default\stale
the-divine-cheese-code\target\default\stale\leiningen.core.classpath.extract-native-dependencies
the-divine-cheese-code\test
the-divine-cheese-code\test\the_divine_cheese_code
the-divine-cheese-code\test\the_divine_cheese_code\core_test.clj
When I run the project with 'lein run' it executes successfully. However, when I open the core.clj file with emacs/cider and try to compile it, I get classpath error.
CompilerException java.io.FileNotFoundException: Could not locate
the_divine_cheese_code/visualization/svg__init.class or
the_divine_cheese_code/visualization/svg.clj on classpath. Please check
that namespaces with dashes use underscores in the Clojure file name.,
compiling:(c:/temp/the-divine-cheese-code/src/the_divine_cheese_code/core.clj:2:1)
CIDER compiles sources sucessfully if I put them in the same directory (changing namespace correspondingly).
(ns the-divine-cheese-code.core)
(require 'the-divine-cheese-code.svg)
(refer 'the-divine-cheese-code.svg)
(def heists [{:location "Cologne, Germany"
...
So maybe the issue is dealt with OS. I use Windows 7, which is not primary OS for Emacs/CIDER.
After some experimenting I found that the CIDER works without :refer
(ns the-divine-cheese-code.core
(:require [the-divine-cheese-code.visualization.svg]))
This looks like a CIDER bug and 'lein run' predictably gives error in this case. If I make it the right way
(ns the-divine-cheese-code.core
(:require [the-divine-cheese-code.visualization.svg :refer :all]))
the CIDER now gives another error:
Caused by java.lang.IllegalStateException
latlng->point already refers to:
#'the-divine-cheese-code.svg/latlng->point in namespace:
the-divine-cheese-code.core
Would suggest to use the options provided by the
ns
macro instead of nakedrequire
andrefer
statements - this is the recommended way of doing imports/requires in Clojure and most of the tooling is written with this way of managing namespaces in mind. Even if the below code still doesn't work in CIDER, it will be easier to diagnose it: