leiningenを使った Clojure 開発
leiningen は clojure版 mavenです。とても便利。
インストールはこのへんを参考にしてください。
現状はlinux版のみ(?)がまともにうごくみたいです。
以降の記事では、clojure 1.1.0 と emacs による開発を想定しています。記事中に間違いなどありましたら指摘をお願いいします。
プロジェクト作成
hogeapp を作ります。$ で始まる行が入力コマンドです。
プロジェクト名 hogeapp は任意ですが、名前に -(ハイフン)を入れるとコンパイルしたファイルが実行時にエラーになってしまうようです。
$ lein new hogeapp Created new project in: hogeapp
カレント以下に自動でいろいろ作られます。
$ find ./hogeapp ./hogeapp ./hogeapp/test ./hogeapp/test/hogeapp ./hogeapp/test/hogeapp/core_test.clj ./hogeapp/.gitignore ./hogeapp/README ./hogeapp/src ./hogeapp/src/hogeapp ./hogeapp/src/hogeapp/core.clj ./hogeapp/project.clj
このうちプログラミングに直接かかわるのはこの3つ。
./hogeapp/test/hogeapp/core_test.clj ./hogeapp/src/hogeapp/core.clj ./hogeapp/project.clj
project.clj はプロジェクトの設定ファイル。
src/hogeapp/core.clj は「ほぼ空」。ネームスペース定義だけ入ってます。
test/hogeapp/core_test.clj は core.clj 用のユニットテストファイルです。
project.clj ファイルの内容
プロジェクトの設定ファイルも clojure プログラム(S式)です。プロジェクト管理にXMLとかいう別言語を使わないのが lisp流みたい。
中身は次のようになってます。
(defproject hogeapp "1.0.0-SNAPSHOT" :description "FIXME: write" :dependencies [[org.clojure/clojure "1.1.0"] [org.clojure/clojure-contrib "1.1.0"]])
defproject でプロジェクトの設定を記述します。
:dependencies の右の[...](ベクタ)の中身は、このプロジェクトで利用するライブラリ(jarファイル)です。ここに書いておくと leiningen が依存関係をチェックしてWEB上リポジトリから依存ファイルを自動ダウンロードしてくれます。
org.clojure/clojure はclojureのコアが入ったライブラリで、clojure-contrib は有志が開発をしている clojure の準標準ライブラリ群です。とりあえずこの二つだけでも色々作れます。
jarファイルのダウンロード
プロジェクトに必要な依存ファイルを最初に取得します。コマンドは lein deps。
new 以外の lein コマンドはすべて project.clj ファイルがあるデリレクトリで行ってください。
$ cd hogeapp $ lein deps Downloading: org/clojure/clojure/1.1.0/clojure-1.1.0.pom from central Downloading: org/clojure/clojure-contrib/1.1.0/clojure-contrib-1.1.0.pom from central Downloading: org/clojure/clojure-contrib/1.1.0/clojure-contrib-1.1.0.pom from clojure Transferring 1K from clojure Downloading: org/clojure/clojure/1.1.0/clojure-1.1.0.jar from central Downloading: org/clojure/clojure-contrib/1.1.0/clojure-contrib-1.1.0.jar from central Downloading: org/clojure/clojure-contrib/1.1.0/clojure-contrib-1.1.0.jar from clojure Transferring 3215K from clojure [copy] Copying 2 files to {path-to}/hogeapp/lib
これは初回実行時の動作です。leiningen は ~/.m2/ デリレクトリ以下にローカルレポジトリを作成し、そこにWEBから必要なファイルをダウンロードします。一度ローカルにダウンロードしてしまえば以降はこのローカルレポジトリからのコピーだけで済むので、download処理は行われません。
jarファイルはプロジェクトのlibデリレクトリに配置されます。
$ ls lib clojure-1.1.0.jar clojure-contrib-1.1.0.jar
clojure-x.x.x.jar は clojure プログラムのコア兼ランタイムです。プロジェクト毎に実行環境を丸ごと作成してしまうのが leiningenの特徴です。これによって全ての依存関係をプロジェクト内だけで解決し、外部ファイルを参照することに起因するトラブルを避けようという思想なのだと思います。
Hello World 作成手順1(エントリポイント指定)
ハローワールドを作ります。まず project.clj の修正から。
(defproject hogeapp "1.0.0-SNAPSHOT" :description "FIXME: write" :dependencies [[org.clojure/clojure "1.1.0"] [org.clojure/clojure-contrib "1.1.0"]] :main hogeapp.core) ;; 追加
プログラムの起点を :main キーワードによって指定します。指定するのはネームスペースです。hogeapp.core は core.clj ので定義されているネームスペースです。
:main を追加するとき、4行目
[org.clojure/clojure-contrib "1.1.0"]])
の末尾の ) を削除するのを忘れないようにしてください。
Hello World 作成手順2(本体コード記述)
core.clj を開いて -main 関数を記述します。
(ns hogeapp.core (:gen-class)) (defn -main [& args] (println "Hello, World!"))
lein でコンパイルしたプログラムは、project.clj の :main で指定したネームスペース(ns)にある、-main 関数を最初に呼出します。
2行目の :gen-class はこのファイルをコンパイル対象にすることを指定しています。この記述がないファイルはコンパイルされません。
Hello World 作成手順3(コンパイル)
jar ファイルに依存ファイルを全てパッキングします。
$ lein compile Compiling hogeapp.core $ lein uberjar All :namespaces already compiled. Created {path-to}/hogeapp/hogeapp.jar Including hogeapp.jar Including clojure-1.1.0.jar Including clojure-contrib-1.1.0.jar
compile は省略していきなり uberjar でも構いません。必要ならばlein が判断して compile も行われます。
カレンドデリレクトリに hogeapp-standalone.jar があればOK
です。