5

我目前正在向 Tomcat 容器中的现有 J2EE webapp 添加功能,并且正在使用 Clojure 编写我的添加。我的设置很简单:我只是添加对 clojure 生成的静态方法的调用,并从 clojure 端编写所有艰苦的工作。构建过程包括编译 clojure 代码 ( lein uberjar),然后在类路径中使用该 jar 编译 java 代码。

在 webapp init 中,我调用了一个生成的类,该类使用(swank/start-repl). 我希望能够将我的 Aquamacs 粘液连接到该服务器,并从那里进行交互工作(到目前为止,我不会尝试任何需要 Java 端重新编译的东西)。但是我有一个我不太了解的情况。如果我执行 a \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)))

假设这是编译并包含在 webapp 加载的 uberjar 中,我可以 eval/inspect my.namespace/*secret*。但是如果我尝试在代码缓冲区内进行评估,Slime 会认为我在user命名空间中(这甚至可以说得通!)。但现在我只剩下一个工作选项——我必须评估——文件中的所有表格!\C-c \C-l(加载源文件)不会做任何事情 - 显然只是返回 nil 并且不输出任何其他内容。编译一切似乎就是这样做的——它会编译,如果找到错误就会显示错误,但不会改变我的命名空间。最奇怪的是\C-~(同步包和目录),它使用 Common Lisp 完成了我想要的,但在这里它永久冻结了 clojure REPL。

始终可以选择切换到 REPL,键入(in-ns 'my.namespace),然后一切正常。但是当 clojure 文件的数量越来越多时,这根本不够实用(因为代码缓冲区的命名空间不会自动更改!)

那么,我的问题是,我是否缺少基本的命令/配置——或者是否有明显的原因导致这种行为发生。

4

3 回答 3

5

我可能误解了你的问题,但你不能(在 emacs 中访问这个假设C-c C-k的缓冲区时)在你当前的 Clojure 实例中编译缓冲区(连接什么 Slime)吗?

然后,在 Slime 缓冲区中,使用(in-ns 'my.namespace). 然后您应该可以访问您在该命名空间中编译的内容。

于 2010-08-12T19:09:38.933 回答
2

在编译时自动切换命名空间从来都不是 swank-clojure 的默认设置,尽管它可能是一个可选的 slime 特性,恰好与 Clojure 一起工作。但是 Cc Mp 将 repl 切换到当前缓冲区的命名空间一直对我有用,而且我从未听说有人遇到过问题。

你是否在最新的稳定版本的 clojure-mode 和 slime-repl 上运行?你安装了 swank-clojure.el 吗?(你不应该需要它。)听起来这可能是由于 elisp 库的版本不匹配。如果这不是问题,则可能是 Aquamacs 错误;swank-clojure 旨在与 GNU Emacs 一起使用。如果您从主干而不是最新的 elpa 版本运行,它也可能是粘液中的错误。

于 2010-08-13T17:48:50.790 回答
1

我刚刚发现 slime-redirect-inferior-output从 slime-repl.el 中删除了这个问题的罪魁祸首,它是从我设置的钩子中调用的。事实证明,如果没有劣质 lisp 进程(阅读,从 emacs 内启动的 swank 服务器),它就不能很好地发挥作用。

因此,一个快速的解决方法就是error从该函数中删除表单,就像这样。现在钩子继续进行,命名空间被自动计算。如预期。不过,感谢您的建议-他们使我找到了这个解决方案!

于 2010-08-21T11:44:11.953 回答