当我评估(使用'hello)加载hello.clj时,REPL会抱怨以下错误:
java.io.FileNotFoundException: Could not locate hello__init.class or hello.clj on classpath: (NO_SOURCE_FILE:0)
Run Code Online (Sandbox Code Playgroud)
我正在调用这样的REPL:
java -cp "/Library/Java/Extensions/servlet-api-2.5-20081211.jar:... lots of jarfiles ...:/Library/Java/Extensions/clojure-contrib.jar:/Library/Java/Extensions/clojure-1.0.0.jar:./classes/:." jline.ConsoleRunner clojure.lang.Repl
Run Code Online (Sandbox Code Playgroud)
阅读,看起来这个文件在PWD中找不到,但我补充说.走向没有成功的道路:-(.
在OS X 10.6上运行Java 1.6.
我确定我是个白痴,有人可以用LART打我吗?
编辑:我也尝试了ClojureX发行版,并得到了相同的结果.
Mic*_*zyk 15
如果在你的类路径hello.clj中$DIR并且$DIR在你的类路径上,则hello.clj需要从头开始(ns hello).如果这是在$DIR/$SUBDIR并$DIR在你的类路径,然后hello.clj就要开始(ns $SUBDIR.hello).通常,您的文件名结构和ns名称结构必须匹配,文件名分隔符用.ns名称替换,文件名中的任何_s对应-于ns名称中的s.实际文件的名称必须是命名空间名称的最终组件(可能是唯一的组件,如果文件包含dir在类路径上).
编辑:
一个扩展的例子.没有超出我上面所写的信息,所以如果这对你来说足够了,请跳过它; 但是我知道在开始时让CP正确对我来说是非常痛苦的,所以我决定一步一步地把它写出来,这样某人,某个地方可能会幸免于那种特殊的"学习经历";-).
假设这是您的命名空间定义:
;;; in file "hello.clj"
(ns hello)
(defn hello []
(println "Hello!"))
Run Code Online (Sandbox Code Playgroud)
然后,如果你把包含hello.clj在你的类路径中的目录放在一起,你就可以去了(use 'hello),REPL应该做你想做的事情.
另一方面,如果你这样做:
;;; in file "hello.clj"
(ns my-namespace)
;;; ...
Run Code Online (Sandbox Code Playgroud)
或这个:
;;; in file "my-filename.clj"
(ns hello)
;;; ...
Run Code Online (Sandbox Code Playgroud)
- 也就是说,如果您在文件名和命名空间名称之间引入不匹配,Clojure将无法找到您的命名空间.
此外,如果您hello.clj输入/path/to/code,但实际上您在类路径上拥有的内容/path/to,即父目录/path/to/code,您需要这样做:
;;; in file "/path/to/code/hello.clj"
(ns code.hello)
;;; ...
Run Code Online (Sandbox Code Playgroud)
然后你就可以了(use 'code.hello).
最后,如果您调用文件my_namespace.clj,则需要调用ns my-namespace(反之亦然).不应使用_命名空间名称中的-s和文件名中的s.
当我从 repl 工作并想要加载文件时,我发现我必须首先调用类似的东西:
(add-classpath "file:///home/arthur/.../src/")
(add-classpath "file:///home/arthur/.../build/")
Run Code Online (Sandbox Code Playgroud)
在 repl 可以在类路径上找到它们之前。我将它们放入一个未包含在 jar 文件中的文件中,并附上一条从其他文件重新加载所有内容的语句。当我构建一个 jar 文件时,我发现我不需要这样做。