很抱歉这篇长篇文章,但是这个论坛总是要求用例: - )。
我经常被要求为我的组织编写实用程序应用程序(GUI和命令行)。我最常用Java编写这些文件,最近用Scala编写。
Clojure(以及其他Lisps)中的“哲学”似乎以REPL为中心,我不得不同意它是一个很好的开发环境,但我显然无法生成需要用户“安装Clojure和Clojure”的实用工具。 -contrib,然后将实用程序解压缩到硬盘驱动器上的目录中,使用以下类路径从命令行启动Clojure,...“。用户并不关心该实用程序是用Clojure编写的。他们只想指向并点击或最多输入“java -jar Utility.jar - ?”在命令行上。
我的问题围绕编译并将应用程序分成许多名称空间/文件。
我知道main
方法必须位于包含(gen-class...)
命令(或:gen-class
命令的ns
子句)的Clojure文件中。我是否对其他Clojure文件执行相同操作,还是将它们作为源代码保留在JAR中并由main
文件加载?如何在开发期间从REPL测试其他文件?
我一直在使用leiningen,cake和maven来构建自包含的JAR(包含解压缩的clojure.jar,clojure-contrib.jar和commons-cli.jar文件),但到目前为止我一直在编写代码在与main
方法相同的文件中。
答案 0 :(得分:1)
您是否将.clj AOT编译为.class或让Clojure在运行时动态执行它取决于您。总的来说,我发现在开发过程中更容易避免使用AOT并且只是将AOT用作性能助推器,以便在运行时编译.clj的成本没有意义(有限的环境,如Google App Engine或实用程序的启动时间)很关键)。对于将运行很长时间的服务器进程,AOT编译没有太大的优势。
在开发时使用AOT类有许多复杂性,这些类特定于不同的开发环境。
AOT的一个缺点是你的编译类可能与Clojure的未来版本不兼容,这比你的clj文件不兼容更有可能。随着时间的推移,这可能变得更加重
答案 1 :(得分:1)
当谈到分离时,我会将它们保存在不同的命名空间/文件中:
:gen-class
命名空间,包含-main
和所有其他类似Java的东西。理想情况下,您的main应该只包含对来自其他命名空间的函数的调用,或者可能包含一些用于评估或重新打包args
的逻辑。
您的问题似乎与逻辑代码和ui代码之间的分离非常相似。您可以看到名称空间:gen-class
只是程序提供给Java代码的接口,仅此而已。
当涉及到实用程序(如命令行或Swing应用程序等)时,由于JVM启动时间,一般会出现Java问题。
现在,你可以通过让服务器应用程序一直在后台运行REPL来解决这个问题,然后说,不知何故接收到要评估的s-expr,并返回结果。这可以作为一个简单的Web应用程序来完成,它接收一个s-expr作为URL参数,并返回结果。现在,通过这个,您可以使用普通的旧Java实现所有实用程序,甚至使用wget进行bash,因为您只需访问URL(假设具有repl的服务器在后台运行)。
这样的事情很有可能已经存在,所以如果有人知道的话 - 评论非常受欢迎。
哦,另外一件事,repl webapp暴露的端口可能必须关闭外部世界,以防止Clojure注入:D