前回leiningenをインストールしたので一番簡単なプロジェクトを作ってみる。
プロジェクト作成
お決まりのHelloWorld
$ lein new helloworld
helloworldというディレクトリが作成され、プロジェクトのスケルトンができてます。中身はこんな感じ
$ find helloworld helloworld/ helloworld/.gitignore helloworld/project.clj helloworld/README helloworld/src helloworld/src/helloworld.clj helloworld/test
project.cljを開いて以下のように追記。
(defproject helloworld "1.0.0-SNAPSHOT" :description "FIXME: write" :dependencies [[org.clojure/clojure "1.1.0-alpha-SNAPSHOT"] [org.clojure/clojure-contrib "1.0-SNAPSHOT"]] ;; 以下追記。スタンドアロンjarのエントリポイント(Javaでいう所の static void main(String[] args)メソッドがあるフネームスペースを指定) :main helloworld )
次にsrc/helloworld.cljを以下のように編集。
(ns helloworld (:gen-class) ) ;; javaでいうpublic static void main(String[] args) (defn -main [& args] (println "Hello World!!") )
REPL起動
lein経由でreplを立ち上げると最初からleinとプロジェクトがクラスパスに入ってます。
$ cd helloworld $ lein repl user=> (use 'clojure.contrib.classpath) user=> (doseq [c (classpath)] (println (.getAbsolutePath c))) /Users/maki/work/clojure/helloworld/src /Users/maki/work/clojure/helloworld/classes /Users/maki/.m2/repository/leiningen/leiningen/1.0.1/leiningen-1.0.1-standalone.jar
さっきの-main関数を使ってみる。
user=> (use 'helloworld) user=> (-main) Hello World!!
ちなみにいま(import 'helloworld)をすると
user=> (import 'helloworld) java.lang.ClassNotFoundException: helloworld (NO_SOURCE_FILE:13)
と怒られます。クラスファイルがないからです。
コンパイル
コンパイルするとclojureのファイルをclassファイルにできます。
$ lein compile [copy] Copying 2 files to /Users/maki/work/clojure/helloworld/lib Compiling helloworld $ find . . ./.gitignore ./classes ./classes/helloworld$_main__14.class ./classes/helloworld$loading__6327__auto____12.class ./classes/helloworld.class ./classes/helloworld__init.class ./lib ./lib/clojure-1.1.0-alpha-20091215.130658-1.jar ./lib/clojure-contrib-1.0-20091212.214557-33.jar ./project.clj (略)
helloworldのクラスファイルとなぜかclojureのjarまでもってきてくれました。これでREPLでimportできそう。
user=> (import 'helloworld) user=> (helloworld/-main) Hello World!!
ちなみにclasspathにもコピーされたjarが追加されてます
user=> (doseq [c (classpath)] (println (.getAbsolutePath c))) /Users/maki/work/clojure/helloworld/src /Users/maki/work/clojure/helloworld/classes /Users/maki/.m2/repository/leiningen/leiningen/1.0.1/leiningen-1.0.1-standalone.jar /Users/maki/work/clojure/helloworld/lib/clojure-1.1.0-alpha-20091215.130658-1.jar /Users/maki/work/clojure/helloworld/lib/clojure-contrib-1.0-20091212.214557-33.jar
実行可能jar作成
REPLで試すのではなく、jarとしてスタンドアロンな実行可能プログラムをつくることもできます。
$ lein uberjar Including helloworld.jar Including clojure-1.1.0-alpha-20091215.130658-1.jar Including clojure-contrib-1.0-20091212.214557-33.jar $ find . . ./.gitignore ./classes ./classes/helloworld$_main__14.class ./classes/helloworld$loading__6327__auto____12.class ./classes/helloworld.class ./classes/helloworld__init.class ./helloworld-standalone.jar ./helloworld.jar ./lib ./lib/clojure-1.1.0-alpha-20091215.130658-1.jar ./lib/clojure-contrib-1.0-20091212.214557-33.jar (略)
helloworld-standalone.jarのエントリポイントがdefprojectで:mainに指定したファイルの-main関数になります(多分)
$ java -jar helloworld-standalone.jar Hello World!!
ちなみに、clojureで作った関数をライブラリ化したのがhelloworld.jarでこれを作るだけならlein jarでおk。
おわり
clojureのプロジェクト管理はleiningenで良さそう。
まだMavenの良さを全く活かしてないサンプルです。
一応Java屋さんってことになっているので今度はMavenを使ったサンプルを作るかも。