---
title: Leiningenでハローワールド
tags: []
categories: ["Programming", "Lisp", "Clojure", "Leiningen"]
date: 2010-01-31T17:03:48Z
updated: 2010-01-31T18:02:27Z
---

<p>
前回leiningenをインストールしたので一番簡単なプロジェクトを作ってみる。
</p>
<h3>プロジェクト作成</h3>
<p>お決まりのHelloWorld</p>
<pre class="prettyprint">
$ lein new helloworld
</pre>
<p>
helloworldというディレクトリが作成され、プロジェクトのスケルトンができてます。中身はこんな感じ
</p>
<pre class="prettyprint">
$ find helloworld
helloworld/
helloworld/.gitignore
helloworld/project.clj
helloworld/README
helloworld/src
helloworld/src/helloworld.clj
helloworld/test
</pre>
<p>
project.cljを開いて以下のように追記。
</p>
<pre class="prettyprint">
(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
  )
</pre>
<p>
次にsrc/helloworld.cljを以下のように編集。
</p>
<pre class="prettyprint">
(ns helloworld
    (:gen-class)
    )
;; javaでいうpublic static void main(String[] args)
(defn -main [& args]
      (println "Hello World!!")
      )
</pre>
<h3>REPL起動</h3>
<p>lein経由でreplを立ち上げると最初からleinとプロジェクトがクラスパスに入ってます。</p>
<pre class="prettyprint">
$ 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
</pre>
<p>
さっきの-main関数を使ってみる。
</p>
<pre class="prettyprint">
user=> (use 'helloworld)
user=> (-main)          
Hello World!!
</pre>
<p>
ちなみにいま(import 'helloworld)をすると
</p>
<pre class="prettyprint">
user=> (import 'helloworld)
java.lang.ClassNotFoundException: helloworld (NO_SOURCE_FILE:13)
</pre>
<p>
と怒られます。クラスファイルがないからです。
</p>
<h3>コンパイル</h3>
<p>コンパイルするとclojureのファイルをclassファイルにできます。</p>
<pre class="prettyprint">
$ 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
(略)
</pre>
<p>
helloworldのクラスファイルとなぜかclojureのjarまでもってきてくれました。これでREPLでimportできそう。
</p>
<pre class="prettyprint">
user=> (import 'helloworld)
user=> (helloworld/-main)
Hello World!!
</pre>
<p>ちなみにclasspathにもコピーされたjarが追加されてます</p>
<pre class="prettyprint">
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
</pre>
<h3>実行可能jar作成</h3>
<p>REPLで試すのではなく、jarとしてスタンドアロンな実行可能プログラムをつくることもできます。</p>
<pre class="prettyprint">
$ 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
(略)
</pre>
<p>helloworld-standalone.jarのエントリポイントがdefprojectで:mainに指定したファイルの-main関数になります（多分）
</p>
<pre class="prettyprint">
$ java -jar helloworld-standalone.jar 
Hello World!!
</pre>
<p>
ちなみに、clojureで作った関数をライブラリ化したのがhelloworld.jarでこれを作るだけならlein jarでおｋ。
</p>
<h3>おわり</h3>
<p>
clojureのプロジェクト管理はleiningenで良さそう。<br/>
まだMavenの良さを全く活かしてないサンプルです。<br/>
一応Java屋さんってことになっているので今度はMavenを使ったサンプルを作るかも。
</p>
