我正在为一个现有的J2EE Webapp添加功能,在Tomcat容器中,使用Clojure编写我的补充。 我的设置很简单:我只需调用由Clojure生成的静态方法,并从Clojure侧编写所有艰苦工作。 构建过程包括编译Clojure代码(lein uberjar
),然后使用该类路径上的jar编译Java代码。
在Webapp init中,我调用了一个生成的类,它启动了一个带有(swank/start-repl)
的Swank服务器。 我想能够将我的Aquamacs的slime连接到该服务器,并从那里进行交互式工作(达到一定程度,我不会尝试需要重新编译Java端的操作)。 但是我遇到了一个我不太理解的情况。 如果我执行\M-x slime-connect
,我会得到一个REPL提示(在被通知没有下位Lisp进程之后,我认为这是可以的,因为下位Lisp进程在Emacs控制之外运行)。 我可以完美地评估形式,甚至可以检查诸如 my.own.namespace / my-var
这样的事物。 但是,如果我访问已经编译的Clojure代码文件,我似乎不能使slime将其识别为源。 考虑一个简单的Clojure文件:
(ns my.namespace
(:gen-class
:name my.namespace
:methods [#^{:static true} [testFunc [] void]]))
(def *secret* "shhhh")
(defn -testFunc []
(println (str "our secret is: " secret)))
假设这个代码被编译并包含在Web应用程序加载的uberjar中,我可以评估/检查`my.namespace / * secret *`。但是,如果我试图在代码缓冲区内评估,Slime会认为我在`user`命名空间中(这甚至可能有意义!)。但现在我只剩下一个可行的选项-我必须逐个评估文件中的所有表单!`\C-c \C-l`(加载源文件)什么都不做- 显然只返回nil并且没有其他输出。编译所有内容似乎就是这样- 它会编译,如果找到错误,则会显示错误,但不会更改我的命名空间。最奇怪的是`\C-〜`(同步软件包和目录),在Common Lisp中使用它正好做我想要的事情,但在这里它会永久冻结clojure REPL。
总之,有一个选择是切换到REPL,键入`(in-ns 'my.namespace)`,然后一切都能正常工作。但是,当Clojure文件数量增加时(因为代码缓冲区的命名空间不会自动更改!),这根本不够实际。
我的问题是,我是否缺少基本的命令/配置-或者这种行为发生的明显原因是什么?
C-c C-k
将编译文件缓冲区中的所有形式,呈现这些形式的错误,并有效地使重新定义(和新定义)的形式动态可用(例如,Web应用程序调用将使用这些新编译的代码)。抱歉我的表述可能不够清晰。 - Edgar GonçalvesM-x swank-clojure-project
启动 SLIME 时所见到的行为:当切换到文件的缓冲区时,命名空间会自动更改,因此在那里评估某些内容将不会使用user
命名空间。或者,使用C-c C-k
/C-c C-l
编译/加载缓冲区应该评估所有表单,包括最初的(ns ...)
,从而切换到特定的命名空间并使所有后续变量属于它。这不是标准设置中预期的行为吗?(我可能看错了...) - Edgar Gonçalves