8.4 新建Counterclockwise项目

尝试使用过Leiningen后,就可在Eclipse IDE中使用Counterclockwise插件创建第一个项目了。

(1) 在Eclipse IDE中,右击Package Explorer的空白处并选择New>Other…。

(2) 在打开的Select a wizard对话框中,选择Clojure>Clojure Project并单击Next按钮。

(3) 将项目名设置为exploring-monads,并确保选择了Leiningen模板default:

8.4 新建Counterclockwise项目 - 图1

(4) 单击Finish按钮生成项目。

8.4 新建Counterclockwise项目 - 图2 注意,在这里可选择Leiningen支持的其他任何模板,但需要注意的是,生成项目时使用的是Counterclockwise内置的Leiningen版本,而这种版本可能不是最新的。你将在本章后面看到,对于这个问题,可通过从命令行创建项目来解决。

项目创建过程需要一段时间。创建完毕后,请在Package Explorer中展开创建的项目,以查看其内容。你应对其目录结构很熟悉。

打开文件src/exploring_monads/core.clj,并在末尾添加如下代码行:

  1. (foo "I'm tired of hearing: ")

为检查Counterclockwise的安装情况,单击Package Explorer中的项目名,再单击Eclipse IDE工具栏中的Run按钮。然后将出现一个对话框,让你选择运行配置;请选择Clojure application并单击OK按钮:

8.4 新建Counterclockwise项目 - 图3

Counterclockwise将加载Clojure REPL,这可能需要一段时间。加载完毕后,将新增一个包含REPL的选项卡。在Eclipse IDE中运行REPL后,就可运行代码了:在Package Explorer中单击文件core.clj,再单击工具栏中的Run按钮。你将在控制台中看到一条非常粗鲁的消息:“I'm tired of hearing: Hello, World!”

8.4.1 Eclipse IDE中的Clojure REPL

项目的Clojure源代码是在运行在Eclipse中的Clojure REPL实例中运行的。REPL窗口包含两个窗格,上面的窗格包含REPL的输出,而下面的窗格可用于输入命令。当你在下面的窗格中输入命令并按回车时,命令将出现在上面的窗格中,然后命令被执行并显示其输出:

8.4 新建Counterclockwise项目 - 图4

你可同时运行多个REPL实例。要再运行一个REPL实例,可单击项目名,再单击工具栏中的Run按钮,并在Eclipse让你选择运行配置时选择Clojure Application。Counterclockwise将询问你是想再启动一个REPL实例,还是使用原来的实例来运行项目的脚本。要启动新实例,可单击OK;要在原来的实例中运行脚本,可单击Cancel。

REPL处于最后一次激活的命名空间中。要在REPL中激活编辑器的当前命名空间,可按Ctrl + Alt + N(在macOS中为cmd + alt + N)。

8.4 新建Counterclockwise项目 - 图5 在REPL中输入命令时,如果出现一条消息,指出命令在当前上下文中找不到,可尝试按组合键Ctrl + Alt + N(在macOS中为cmd + alt + N)来切换命名空间。

8.4.2 更新项目的Clojure版本

选择的默认Clojure版本可能不是最新的。由于我们在Counterclockwise中选择使用了最新的Leiningen版本,因此可以更新Clojure版本。为此,在Package Explorer中打开构建文件project.clj。务必要打开project.clj,而不是同一个目录下包含Eclipse项目文件定义的.project文件。前面说过,project.clj是Leiningen构建文件,用于构建和运行项目。在我的系统中,这个文件类似于下面这样:

  1. (defproject exploring-monads "0.1.0-SNAPSHOT"
  2. description "FIXME: write description"
  3. :url "http://example.com/FIXME"
  4. :license {:name "Eclipse Public License"
  5. :url "http://www.eclipse.org/legal/epl-v10.html"}
  6. :dependencies [[org.clojure/clojure "1.6.0"]]
  7. :main ^:skip-aot exploring-monads.core
  8. :target-path "target/%s"
  9. :profiles {:uberjar {:aot :all}})

从中可知,Leiningen使用Clojure源代码来定义项目及其构建需求。这与Maven等构建工具不同,它们使用XML文件来存储这种信息。实际上,这淋漓尽致地展示了Clojure的代码即数据数据即代码原则。这个构建文件是使用Leiningen宏defproject定义的,这个宏将一些特定的关键字(以冒号打头的单词)及其值作为参数。

defproject宏的参数包含大量元数据,如项目描述、项目URL和许可证等。:main键指出程序运行时调用的函数main是在命名空间exploring-monads.core中定义的,这个命名空间对应于子目录src/exploringmonads中的文件core.clj。:dependencies键指定了当前依赖。当前,这个项目唯一的依赖项是Clojure 1.6。

:aot引用处理的是Clojure的预先(ahead of time,AOT)编译功能。它决定了使用编译任务时,将把哪些命名空间编译到类文件中。如果将值设置为:all,就意味着将编译所有命名空间,对任务uberjar来说,这是合适的。对于main函数,通常忽略AOT功能,为此可指定元数据设置^:skip-aot

为更新这个项目将使用的Clojure版本,请执行如下操作。

(1) 修改:dependencies部分的版本号。本书出版时,最新的Clojure版本为1.8.0,因此我将1.6.0改为1.8.0。

(2) 按Ctrl + S(在macOS中为cmd + S)将文件存盘。Counterclockwise将立即更新项目,并将Clojure版本替换为你指定的版本。

(3) 单击REPL选项卡的Close图标将其关闭。再次打开文件core.clj,并单击工具栏中的Run图标,你将看到新指定的Clojure版本支持的REPL选项卡。

8.4.3 添加依赖

我们需要使用monads库。请访问这个项目的主页https://github.com/clojure/algo.monads,以了解最新版本以及必须向Leiningen提供的依赖信息。

编写本书期间,最新版为0.1.6,而Leiningen依赖信息可在monads的项目主页中找到。我看到的情况如下:

  1. [org.clojure/algo.monads "0.1.6"]

请在Eclipse中打开文件build.clj,并添加这个新依赖:在:dependencies向量中添加上述向量。添加这个依赖后,:dependencies行应类似于下面这样:

  1. :dependencies [[org.clojure/clojure "1.8.0"],
  2. [org.clojure/algo.monads "0.1.6"]]

按Ctrl + S将文件存盘,Counterclockwise将立即更新项目。此时如果你在Package Explorer中展开条目Leiningen dependencies,将看到其中包含algo.monads库:

8.4 新建Counterclockwise项目 - 图6