<?xml version="1.0" encoding="utf-8" ?>


<?xml-stylesheet href="http://d.hatena.ne.jp/ayu_standalone/rssxsl" type="text/xsl" media="screen"?>


<rdf:RDF
xmlns="http://purl.org/rss/1.0/"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xml:lang="ja">
<channel rdf:about="http://d.hatena.ne.jp/ayu_standalone/rss">
<title>you know something? | Use it for myself.</title>
<link>http://d.hatena.ne.jp/ayu_standalone/</link>
<description>you know something? | Use it for myself.</description>

<dc:creator>ayu_standalone</dc:creator>
<dc:date>2011-06-17T11:26:01+09:00</dc:date>
<items>
<rdf:Seq>
<rdf:li rdf:resource="http://d.hatena.ne.jp/ayu_standalone/20110617/1308277560"/>
<rdf:li rdf:resource="http://d.hatena.ne.jp/ayu_standalone/20110616/1308193691"/>
<rdf:li rdf:resource="http://d.hatena.ne.jp/ayu_standalone/20110614/1308031691"/>
<rdf:li rdf:resource="http://d.hatena.ne.jp/ayu_standalone/20110614/1308044840"/>
<rdf:li rdf:resource="http://d.hatena.ne.jp/ayu_standalone/20110612/1307834311"/>
<rdf:li rdf:resource="http://d.hatena.ne.jp/ayu_standalone/20110308/1299573297"/>
</rdf:Seq>
</items>
</channel>



<item rdf:about="http://d.hatena.ne.jp/ayu_standalone/20110617/1308277560">
<title>[textmate][clojure] TextMate で Clojure のソースを快適にインデント！</title>
<link>http://d.hatena.ne.jp/ayu_standalone/20110617/1308277560</link>
<description> Clojure のソースを TextMate で書き綴って、REPL で実行するプロセスはとても快適ではありますが、一点ほど難点があります。それはインデントです。 python でも同様の症状が発生しますが、ruby のようにブロックの終端を表わすブレースなどが行頭に戻って来ないソース形式</description>

<content:encoded><![CDATA[
<div class="section">
<p>Clojure のソースを TextMate で書き綴って、REPL で実行するプロセスはとても快適ではありますが、一点ほど難点があります。それはインデントです。</p>
<p>python でも同様の症状が発生しますが、ruby のようにブロックの終端を表わすブレースなどが行頭に戻って来ないソース形式の場合、TextMate ではインデントが正常に動作しません。</p>
<p>仕方ありませんので、python では、<a href="http://pypi.python.org/pypi/PythonTidy/" target="_blank">Python Package Index : PythonTidy 1.20</a> を呼び出して代用しておりましたが、どうも Clojure でも同様の処置を施さねばならないようです。</p>
<br>

<p>Google 先生によると、こちらを</p>
<p>(参考) <a href="http://b.hatena.ne.jp/entry/manjilab.com/2009/11/13/indent-clojure-in-textmate/" target="_blank">はてなブックマーク - TextMateでのClojureのインデント解決編 - マンジラボ</a></p>
<p>参考にせよ、との思し召しなのですが、残念ながら、当該サイトは閉鎖、ないしはメンテナンスされていない状態のようです。</p>
<p>ブクマに残されたコメントから推察するに、Emacs の clojure-mode を呼び出してコード整形を果たしている様子。その辺から Google 先生にお問い合わせすると....</p>
<p>(参考) <a href="http://www.flickr.com/photos/manjilab/4097992719/sizes/z/in/photostream/" target="_blank">All sizes | Tidy up clojure code in TextMate | Flickr - Photo Sharing!</a></p>
<p>有りましたぁ！なんと、コードの断片を画像で発見してしまいましたよw</p>
<br>

<p>この画像を写経することでキレイなインデントを獲得することができました。以下が Command(s) に埋め込むコードです。</p>
<pre class="syntax-highlight">
<span class="synPreProc">#!/usr/bin/env ruby</span>

filename = <span class="synSpecial">&#34;</span><span class="synConstant">/tmp/tmptx_tidyup_code.clj</span><span class="synSpecial">&#34;</span>;

<span class="synIdentifier">File</span>.open(filename, <span class="synSpecial">&#34;</span><span class="synConstant">w</span><span class="synSpecial">&#34;</span>) {|<span class="synIdentifier">f</span>|
  <span class="synIdentifier">STDIN</span>.each <span class="synStatement">do</span> |<span class="synIdentifier">line</span>|
    f.print line
  <span class="synStatement">end</span>
}

<span class="synComment"># path は clojure-mode.el を保存したパスに変更してください</span>
<span class="synComment"># lisp-indent-offset は好みのインデント幅に変更してください</span>

result = <span class="synSpecial">`</span><span class="synConstant">/usr/bin/emacs -batch \</span>
<span class="synConstant">--eval '(load &#34;/path/clojure-mode.el&#34;)' \</span>
<span class="synSpecial">#{filename}</span><span class="synConstant"> \</span>
<span class="synConstant">--eval '(setq indent-tabs-mode nil)' \</span>
<span class="synConstant">--eval '(setq lisp-indent-offset 4)' \</span>
<span class="synConstant">--eval '(indent-region (point-min) (point-max) nil)' \</span>
<span class="synConstant">-f save-buffer &#38;&#62; /dev/null</span><span class="synSpecial">`</span>

puts <span class="synSpecial">`</span><span class="synConstant">cat </span><span class="synSpecial">#{filename}`</span>
</pre>

<br>

<p>いやいや。これで閉じ括弧を先頭に持って来るような、無様なことをせずに済みます。</p>
</div>
]]></content:encoded>
<dc:creator>ayu_standalone</dc:creator>
<dc:date>2011-06-17T11:26:00+09:00</dc:date>
<dc:subject>textmate</dc:subject>
<dc:subject>clojure</dc:subject>
</item>
<item rdf:about="http://d.hatena.ne.jp/ayu_standalone/20110616/1308193691">
<title>[GAE][slim3][clojure]「Clojure と slim3」の夏がやってくる (其の四)</title>
<link>http://d.hatena.ne.jp/ayu_standalone/20110616/1308193691</link>
<description> 忠実に Junit4 を再現しようとして、いささか躓いてしまいましたが、ヒントは Scala の Slim3 対応にありました。 (参考) Slim3をScalaで動かすためのいろいろ - ゆろよろ日記 package slim3scala.controller.Foo import org.specs.Specification import org.specs.runner._</description>

<content:encoded><![CDATA[
<div class="section">
<p>忠実に Junit4 を再現しようとして、いささか躓いてしまいましたが、ヒントは Scala の Slim3 対応にありました。</p>
<br>

<p>(参考) <a href="http://d.hatena.ne.jp/yuroyoro/20100319/1269002829" target="_blank">Slim3をScalaで動かすためのいろいろ - ゆろよろ日記</a></p>
<pre class="syntax-highlight">
package slim3scala.controller.Foo

import org.specs.Specification
import org.specs.runner._
import org.slim3.tester.ControllerTester

object IndexControllerSpec extends org.specs.Specification {

  val tester = new ControllerTester( classOf[IndexController] )

(以下略)
</pre>

<p>要は、ControllerTester や AppEngineTester さえ生成できれば、Clojure 由来のテスト環境でまったく問題無い、ということになります。</p>
<p>切っ掛けとなった <a href="http://d.hatena.ne.jp/yuroyoro/">id:yuroyoro</a> さんには本当に感謝です。</p>
<br>

<p>そこで、まずは、コントローラーのテストです。</p>
<h4> IndexControllerTest.clj</h4>
<pre class="syntax-highlight">
<span class="synSpecial">(</span>ns com.example.controller.IndexControllerTest
    <span class="synSpecial">(</span>:import
        com.example.controller.IndexController,
        javax.servlet.http.HttpServletResponse,
        org.slim3.tester.ControllerTester<span class="synSpecial">)</span>
    <span class="synSpecial">(</span><span class="synType">:use</span> clojure.contrib.test-is<span class="synSpecial">))</span>


<span class="synSpecial">(</span>defn setup-fixtures
    <span class="synConstant">&#34;Docstring for setup-fixtures.&#34;</span>
    [test-func]

    <span class="synSpecial">(</span>def tester <span class="synSpecial">(</span>ControllerTester. <span class="synSpecial">(</span>.. <span class="synSpecial">(</span>IndexController.<span class="synSpecial">)</span> getClass<span class="synSpecial">)))</span>
    <span class="synSpecial">(</span>.setUp tester<span class="synSpecial">)</span>
    <span class="synSpecial">(</span>.start tester <span class="synConstant">&#34;/&#34;</span><span class="synSpecial">)</span>
    <span class="synSpecial">(</span>test-func<span class="synSpecial">)</span>
    <span class="synSpecial">(</span>.tearDown tester<span class="synSpecial">))</span>
<span class="synSpecial">(</span>use-fixtures :each setup-fixtures<span class="synSpecial">)</span>


<span class="synSpecial">(</span>deftest test-sample
    <span class="synConstant">&#34;Docstring for -run.&#34;</span>

    <span class="synSpecial">(</span>is <span class="synSpecial">(</span><span class="synStatement">=</span> <span class="synSpecial">(</span>.. HttpServletResponse SC_OK<span class="synSpecial">)</span> <span class="synSpecial">(</span>.getStatus <span class="synSpecial">(</span>.. tester response<span class="synSpecial">)))))</span>
</pre>

<br>

<p>次に、サービスのテストです。</p>
<h4> Slim3ServiceTest.clj</h4>
<pre class="syntax-highlight">
<span class="synSpecial">(</span>ns com.example.service.Slim3ServiceTest
    <span class="synSpecial">(</span>:import
        com.example.service.Slim3Service,
        org.slim3.tester.AppEngineTester<span class="synSpecial">)</span>
    <span class="synSpecial">(</span><span class="synType">:use</span> clojure.contrib.test-is<span class="synSpecial">))</span>


<span class="synSpecial">(</span>defn setup-fixtures
    <span class="synConstant">&#34;Docstring for setup-fixtures.&#34;</span>
    [test-func]

    <span class="synSpecial">(</span>def tester <span class="synSpecial">(</span>AppEngineTester.<span class="synSpecial">))</span>
    <span class="synSpecial">(</span>.setUp tester<span class="synSpecial">)</span>
    <span class="synSpecial">(</span>test-func<span class="synSpecial">)</span>
    <span class="synSpecial">(</span>.tearDown tester<span class="synSpecial">))</span>
<span class="synSpecial">(</span>use-fixtures :each setup-fixtures<span class="synSpecial">)</span>


<span class="synSpecial">(</span>deftest test-sample
    <span class="synConstant">&#34;Docstring for -run.&#34;</span>

    <span class="synSpecial">(</span>Slim3Service/newAndPut <span class="synConstant">&#34;abc&#34;</span><span class="synSpecial">)</span>
    <span class="synSpecial">(</span>is <span class="synSpecial">(</span><span class="synStatement">=</span> <span class="synConstant">1</span> <span class="synSpecial">(</span>.. <span class="synSpecial">(</span>Slim3Service/queryAll<span class="synSpecial">)</span> size<span class="synSpecial">))))</span>
</pre>

<br>

<p>これを</p>
<pre class="syntax-highlight">
$ mvn <span class="synStatement">test</span>
</pre>

<p>で実行してあげると....</p>
<pre class="syntax-highlight">
<span class="synStatement">(</span>前略<span class="synStatement">)</span>
-------------------------------------------------------
 T E S T S
-------------------------------------------------------
There are no tests to run.

Results :

Tests run: <span class="synConstant">0</span>, Failures: <span class="synConstant">0</span>, Errors: <span class="synConstant">0</span>, Skipped: <span class="synConstant">0</span>
<span class="synComment"># ↑ こちらは Java のテスト結果</span>

<span class="synStatement">[</span>INFO<span class="synStatement">]</span> <span class="synStatement">[</span>clojure:<span class="synStatement">test</span> <span class="synSpecial">{</span>execution: <span class="synStatement">test</span>-clojure<span class="synSpecial">}</span>]

(中略)

Ran <span class="synConstant">2</span> tests containing <span class="synConstant">2</span> assertions.
<span class="synConstant">0</span> failures, <span class="synConstant">0</span> errors.
<span class="synComment"># ↑ こちらが Clojure のテスト結果</span>

(以下略)
</pre>

<p>はい。無事成功となりました。</p>
<p>余談ではありますが、Clojure のテストは俗に言う setUp や tearDown にクロージャーを上手く取り入れていて、大変分かりやすいですね。</p>
<p>さぁ、これで一通り、準備は完了です。</p>
<p>さぁて、Clojure と Slim3 で、この夏、何を作ろうかな？</p>
</div>
]]></content:encoded>
<dc:creator>ayu_standalone</dc:creator>
<dc:date>2011-06-16T12:08:11+09:00</dc:date>
<dc:subject>GAE</dc:subject>
<dc:subject>slim3</dc:subject>
<dc:subject>clojure</dc:subject>
</item>
<item rdf:about="http://d.hatena.ne.jp/ayu_standalone/20110614/1308031691">
<title>[GAE][slim3][clojure]「Clojure と slim3」の夏がやってくる (其の弐)</title>
<link>http://d.hatena.ne.jp/ayu_standalone/20110614/1308031691</link>
<description> (其の壱) で これで、コントローラーの Clojure 化を無事果たすことができました。 次は、サービスの Clojure 化に挑戦してみたいと思います。 と申し上げたのですが、maven が生成する初期プロジェクトのコントローラーとサービスの Clojure 化を目指すことに変更しました</description>

<content:encoded><![CDATA[
<div class="section">
<p> (其の壱) で</p>
<blockquote>
<p>これで、コントローラーの Clojure 化を無事果たすことができました。</p>
<p>次は、サービスの Clojure 化に挑戦してみたいと思います。</p>
</blockquote>
<p>と申し上げたのですが、maven が生成する初期プロジェクトのコントローラーとサービスの Clojure 化を目指すことに変更しました。</p>
<p>取りあえず、出来上がった IndexController.clj は下記の通りです。</p>
<h4> IndexController.clj</h4>
<pre class="syntax-highlight">
<span class="synSpecial">(</span>ns com.example.controller.IndexController
    <span class="synSpecial">(</span>:gen-class
        :extends org.slim3.controller.Controller
        :exposes {response {:get getResponce, :set setResponce}}
        :exposes-methods {forward forwardS, requestScope requestScopeS}<span class="synSpecial">)</span>
    <span class="synSpecial">(</span>:import
        com.example.meta.Slim3ModelMeta,
        com.example.model.Slim3Model,
        java.util.Date,
        org.slim3.datastore.Datastore<span class="synSpecial">))</span>


<span class="synSpecial">(</span>defn -run
    <span class="synConstant">&#34;Docstring for -run.&#34;</span>
    [this]

    <span class="synSpecial">(</span><span class="synStatement">let</span> [res <span class="synSpecial">(</span>.. this getResponce<span class="synSpecial">)</span>]
        <span class="synSpecial">(</span>.println <span class="synSpecial">(</span>.. res getWriter<span class="synSpecial">)</span> <span class="synConstant">&#34;Hello, World!&#34;</span><span class="synSpecial">)</span>

        <span class="synSpecial">(</span><span class="synStatement">let</span> [model <span class="synSpecial">(</span>Slim3Model.<span class="synSpecial">)</span>]
            <span class="synSpecial">(</span>.setProp1 model <span class="synSpecial">(</span>.. <span class="synSpecial">(</span>Date.<span class="synSpecial">)</span> toString<span class="synSpecial">))</span>
            <span class="synSpecial">(</span>Datastore/put model<span class="synSpecial">))</span>

        <span class="synSpecial">(</span>doseq [x <span class="synSpecial">(</span>.. <span class="synSpecial">(</span>Datastore/query <span class="synSpecial">(</span>Slim3ModelMeta/get<span class="synSpecial">))</span> asList<span class="synSpecial">)</span>]
            <span class="synSpecial">(</span>.println <span class="synSpecial">(</span>.. res getWriter<span class="synSpecial">)</span> <span class="synSpecial">(</span>.. x getProp1<span class="synSpecial">)))</span>

        <span class="synSpecial">(</span>.flushBuffer res<span class="synSpecial">)))</span>
</pre>

<p>Java の IndexController 同様、"Hello World!" を出力した後、put した Slim3Model の query 結果から順次 prop1 の内容を出力します。</p>
<p>さて、次は、今度こそ、サービスの Clojure 化に挑戦してみたいと思います。</p>
<br>

<p>追伸: しかし、本当に Clojure のソースは美しいですね。もう 、ちょっと Java には戻れませんって。</p>
</div>
]]></content:encoded>
<dc:creator>ayu_standalone</dc:creator>
<dc:date>2011-06-14T15:08:11+09:00</dc:date>
<dc:subject>GAE</dc:subject>
<dc:subject>slim3</dc:subject>
<dc:subject>clojure</dc:subject>
</item>
<item rdf:about="http://d.hatena.ne.jp/ayu_standalone/20110614/1308044840">
<title>[GAE][slim3][clojure]「Clojure と slim3」の夏がやってくる (其の参)</title>
<link>http://d.hatena.ne.jp/ayu_standalone/20110614/1308044840</link>
<description> さて、サービスの Clojure 化です。 本当は Pure Clojure で行きたかったところですが、そうすると、せっかくの Hot Reloading を無効にせねばなりません。 そうでなくとも、ゆとり Eclipse 世代w としては手動ビルドさえ面倒な状況ですから、ビルドのたびに開発サーバの再</description>

<content:encoded><![CDATA[
<div class="section">
<p>さて、サービスの Clojure 化です。</p>
<p>本当は Pure Clojure で行きたかったところですが、そうすると、せっかくの Hot Reloading を無効にせねばなりません。</p>
<p>そうでなくとも、ゆとり Eclipse 世代w としては手動ビルドさえ面倒な状況ですから、ビルドのたびに開発サーバの再起動なんてやってられません。</p>
<p>なので、止むを得ず Java クラスとして扱うこととしました。</p>
<p>まずは、サービスのコードです。</p>
<h4> Slim3Service.clj</h4>
<pre class="syntax-highlight">
<span class="synSpecial">(</span>ns com.example.service.Slim3Service
    <span class="synSpecial">(</span>:gen-class
        :methods [
                     #^{:static true} [newAndPut [String] void],
                     #^{:static true} [queryAll [] java.util.List]]<span class="synSpecial">)</span>
    <span class="synSpecial">(</span>:import
        com.example.meta.Slim3ModelMeta,
        com.example.model.Slim3Model,
        com.google.appengine.api.datastore.Key,
        java.util.List,
        org.slim3.datastore.Datastore<span class="synSpecial">))</span>


<span class="synSpecial">(</span>defn -newAndPut
    <span class="synConstant">&#34;Docstring for new-and-put [prop1].&#34;</span>
    [prop1]

    <span class="synSpecial">(</span><span class="synStatement">let</span> [model <span class="synSpecial">(</span>Slim3Model.<span class="synSpecial">)</span>]
        <span class="synSpecial">(</span>.setProp1 model prop1<span class="synSpecial">)</span>
        <span class="synSpecial">(</span><span class="synStatement">let</span> [key <span class="synSpecial">(</span>Datastore/put model<span class="synSpecial">)</span>]
            <span class="synSpecial">(</span>.setKey model key<span class="synSpecial">))))</span>

<span class="synSpecial">(</span>defn -queryAll
    <span class="synConstant">&#34;Docstring for queryAll.&#34;</span>
    []

    <span class="synSpecial">(</span>.. <span class="synSpecial">(</span>Datastore/query <span class="synSpecial">(</span>Slim3ModelMeta/get<span class="synSpecial">))</span> asList<span class="synSpecial">))</span>
</pre>

<br>

<p>次に、作成したサービスを使用するよう、コントローラーを変更します。</p>
<h4> IndexController.clj</h4>
<pre class="syntax-highlight">
<span class="synSpecial">(</span>ns com.example.controller.IndexController
    <span class="synSpecial">(</span>:gen-class
        :extends org.slim3.controller.Controller
        :exposes {response {:get getResponce, :set setResponce}}
        :exposes-methods {forward forwardS, requestScope requestScopeS}<span class="synSpecial">)</span>
    <span class="synSpecial">(</span>:import
        com.example.meta.Slim3ModelMeta,
        com.example.model.Slim3Model,
        com.example.service.Slim3Service,
        java.util.Date,
        org.slim3.datastore.Datastore<span class="synSpecial">))</span>


<span class="synSpecial">(</span>defn -run
    <span class="synConstant">&#34;Docstring for -run.&#34;</span>
    [this]

    <span class="synSpecial">(</span><span class="synStatement">let</span> [res <span class="synSpecial">(</span>.. this getResponce<span class="synSpecial">)</span>]
        <span class="synSpecial">(</span>.println <span class="synSpecial">(</span>.. res getWriter<span class="synSpecial">)</span> <span class="synConstant">&#34;Hello, World!&#34;</span><span class="synSpecial">)</span>

        <span class="synSpecial">(</span>Slim3Service/newAndPut <span class="synSpecial">(</span>.. <span class="synSpecial">(</span>Date.<span class="synSpecial">)</span> toString<span class="synSpecial">))</span>

        <span class="synSpecial">(</span>doseq [x <span class="synSpecial">(</span>Slim3Service/queryAll<span class="synSpecial">)</span>]
            <span class="synSpecial">(</span>.println <span class="synSpecial">(</span>.. res getWriter<span class="synSpecial">)</span> <span class="synSpecial">(</span>.. x getProp1<span class="synSpecial">)))</span>

        <span class="synSpecial">(</span>.flushBuffer res<span class="synSpecial">)))</span>
</pre>

<p>Java クラスの扱いの勘所が分かってくると、スイスイ記述できますね。本当に素晴らしいです。</p>
<p>さて、次は、本来であれば先に行なうべきなのですが、TestCase を記述してみたいと思います。</p>
</div>
]]></content:encoded>
<dc:creator>ayu_standalone</dc:creator>
<dc:date>2011-06-14T18:47:20+09:00</dc:date>
<dc:subject>GAE</dc:subject>
<dc:subject>slim3</dc:subject>
<dc:subject>clojure</dc:subject>
</item>
<item rdf:about="http://d.hatena.ne.jp/ayu_standalone/20110612/1307834311">
<title>[clojure][slim3][GAE] 「Clojure と slim3」の夏がやってくる (其の壱)</title>
<link>http://d.hatena.ne.jp/ayu_standalone/20110612/1307834311</link>
<description> 最近、ようやく AppEngine にというか、KVS の扱いに慣れてきたように思います。 Rails や Django では常に DRY であること要求されますが、その無言の圧力に従っていれば、自然とアプリ全体が見通しの良い構造になっていきます。 ある意味、考え無しでも、そこそこのモノが</description>

<content:encoded><![CDATA[
<div class="section">
<p>最近、ようやく AppEngine にというか、KVS の扱いに慣れてきたように思います。</p>
<p>Rails や Django では常に DRY であること要求されますが、その無言の圧力に従っていれば、自然とアプリ全体が見通しの良い構造になっていきます。</p>
<p>ある意味、考え無しでも、そこそこのモノができてしまいますので、実力が上がったように思いがちですが、実際はフレームワークの力によるもの、ということが往々にしてあります。</p>
<p>反面、GAE では製作者の技量が試されるような気がします。</p>
<p>ここは、規定時間内に処理が終了さえすれば、何も問われない世界です。だからと言って、何も考えずにアプローチしていては、この GAE というコースは攻略できません。</p>
<p>DRY ばかりを推し進めてもウマく行きません。さりとて、正規化を外しまくると管理が大変になってしまいます。とにかくバランスがとても大切で、この感覚を定着させるまでが一苦労でした。</p>
<p>「各種 API へのアクセスを可能な限り減らして、インスタンス内で高速にデータ処理する」というサイクルを、製作するアプリの性質ごとに最適化していくプロセスは、ちょっとしたパズルのようで、個人的には一番楽しい時間でもあります (ちなみに、一番キライなのはページ作りw)</p>
<p>ただ、先日発表になった新料金プランによって敷居が更に上がったような気がします。これからは、もっと妥協無く上記サイクルを徹底しないと利用料金を低く抑えられません (面倒になってしまって、手綱を緩めてしまうこと多々&#60;涙&#62;)</p>
<p>Rails のような FW とは異なり、AppEngine では、データとコードが相当なレベルで分離されていません。KVS からリスト構造を取得して、そのリストがコードに変化してユーザに届くような感じで、この感覚は正に Lisp であります。</p>
<p>そういう意味で、リストが扱いづらい Java への不満が募り始めたところでありました (ちなみに、Java の方がテスト環境の構築が容易であることを考慮すると、pytyon という選択肢は残念ながら有り得ません)</p>
<p>そこで、JVM 上の Lisp と言えば Clojure。Slim3 を Clojure から操れないか、試してみました。</p>
<br>

<p>まずは、プロジェクトの作成から。Jenkins から扱いやすいよう maven で生成します。</p>
<pre class="syntax-highlight">
$ mvn archetype:generate -DarchetypeCatalog<span class="synStatement">=</span>http://slim3.googlecode.com/svn/trunk/repository

<span class="synStatement">(</span>中略<span class="synStatement">)</span>
Define value <span class="synStatement">for</span> property <span class="synConstant">'groupId'</span>: : com.example
Define value <span class="synStatement">for</span> property <span class="synConstant">'artifactId'</span>: : CljTest
<span class="synStatement">(</span>以下略<span class="synStatement">)</span>
</pre>

<br>

<p>次に、pom.xml を修正して Clojure 関連ツールの導入準備をします。</p>
<p>(参考) <a href="http://www.brainsellers.com/blog/inastream/2010/08/clojure-02.html" target="_blank">Clojureでの開発環境 - in a Stream</a></p>
<br>

<p>次に、プロジェクトを maven で Eclipse 化して Eclipse へインポートします。</p>
<pre class="syntax-highlight">
$ mvn eclipse:eclipse
</pre>

<br>

<p>これで、Eclipse で編集できるようになりました。試してみたところ、Hot Reloading は有効のようです。</p>
<p>ただ、Eclipse の自動ビルドではコンパイルしてくれないので、手動でコンパイルする必要があります。</p>
<pre class="syntax-highlight">
$ mvn compile <span class="synStatement">(</span>含む Java ファイル<span class="synStatement">)</span>
    or
$ mvn clojure:compile <span class="synStatement">(</span>Clojure ファイルのみ<span class="synStatement">)</span>
</pre>

<p>また、せっかくコンパイルした Clojure 由来のクラスファイルを消されてしまいますので、Eclipse の「Project メニュ → Build Automatically」のチェックを外しておきます。</p>
<br>

<p>さぁ、これで準備完了です。</p>
<p>手始めに maven が生成した IndexController を置き換えてみたいと思います。</p>
<p>まずは、src/main/java/com/example/controller/IndexController.java を削除します。</p>
<p>次に、src/main/clojure/com/example/controller/IndexController.clj と war/index.jsp を作成します。</p>
<br>

<h4> IndexController.clj </h4>
<pre class="syntax-highlight">
<span class="synSpecial">(</span>ns com.example.controller.IndexController
    <span class="synSpecial">(</span>:gen-class :extends org.slim3.controller.Controller
    :exposes-methods {forward forwardSuper, requestScope requestScopeSuper}<span class="synSpecial">))</span>


<span class="synSpecial">(</span>defn -run
    <span class="synConstant">&#34;Docstring for -run.&#34;</span>
    [this]

    <span class="synSpecial">(</span>. this requestScopeSuper <span class="synConstant">&#34;msg&#34;</span>, <span class="synConstant">&#34;OK?&#34;</span><span class="synSpecial">)</span>
    <span class="synSpecial">(</span>. this forwardSuper <span class="synConstant">&#34;index.jsp&#34;</span><span class="synSpecial">))</span>

<span class="synComment">;; 余談ではありますが、Java のソースと比べると圧到的に美しいですねぇ (主観 100%)</span>
</pre>

<h4> index.jsp</h4>
<pre class="syntax-highlight">
<span class="synIdentifier">&#60;!DOCTYPE HTML&#62;</span>
<span class="synIdentifier">&#60;</span><span class="synStatement">html</span><span class="synIdentifier">&#62;</span>
<span class="synIdentifier">&#60;</span><span class="synStatement">body</span><span class="synIdentifier">&#62;</span>
  <span class="synIdentifier">&#60;</span><span class="synStatement">h1</span><span class="synIdentifier">&#62;</span>Hello, World!! ${msg}<span class="synIdentifier">&#60;/</span><span class="synStatement">h1</span><span class="synIdentifier">&#62;</span>
<span class="synIdentifier">&#60;/</span><span class="synStatement">body</span><span class="synIdentifier">&#62;</span>
<span class="synIdentifier">&#60;/</span><span class="synStatement">html</span><span class="synIdentifier">&#62;</span>
</pre>

<br>

<p>最後に、Eclipse の「Run メニュ → Run As → Web Application」を実行した後、</p>
<pre class="syntax-highlight">
$ mvn clojure:compile
</pre>

<p>を実行して <a href="http://localhost:8888/" target="_blank">http://localhost:8888/</a> にアクセスしてみましょう。</p>
<pre class="syntax-highlight">
Hello, World!! OK?
</pre>

<p>と表示されれば、成功です。</p>
<br>

<p>これで、コントローラーの Clojure 化を無事果たすことができました。</p>
<p>次は、サービスの Clojure 化に挑戦してみたいと思います。</p>
</div>
]]></content:encoded>
<dc:creator>ayu_standalone</dc:creator>
<dc:date>2011-06-12T08:18:31+09:00</dc:date>
<dc:subject>clojure</dc:subject>
<dc:subject>slim3</dc:subject>
<dc:subject>GAE</dc:subject>
</item>
<item rdf:about="http://d.hatena.ne.jp/ayu_standalone/20110308/1299573297">
<title>[eclipse] 生産性が求められる「今」だからこそ、Eclipse を使おう！</title>
<link>http://d.hatena.ne.jp/ayu_standalone/20110308/1299573297</link>
<description> 私と Eclipse の不幸な出会い 今から 7年ほど前まで遡りますが、そのころの私は Java ベースの WebObjects で開発を行なっておりました。開発環境は当然ながら、Xcode。 しかし、私のスキルの問題も多分にあったと思うのですが、なかなか効率が上がらない WebObjects のスタ</description>

<content:encoded><![CDATA[
<div class="section">
<h4> 私と Eclipse の不幸な出会い</h4>
<p>今から 7年ほど前まで遡りますが、そのころの私は Java ベースの WebObjects で開発を行なっておりました。開発環境は当然ながら、Xcode。</p>
<p>しかし、私のスキルの問題も多分にあったと思うのですが、なかなか効率が上がらない WebObjects のスタイルに嫌気が差していた私は、そこから離れて PHP に鞍替えすることにしました。</p>
<p>問題は開発環境です。IDE に慣れていたので、PHP でもやはり同様なモノが欲しいと思っていたところ、遭遇したのが TruStudio。これが形を変えた Eclipse との出会いでした。</p>

<ul>
<li> <a href="http://www.eclipsewiki.net/eclipse/index.php?TruStudio" target="_blank">TruStudio - EclipseWiki</a></li>
</ul>
<p>しかし...</p>
<blockquote>
<p><span style="font-weight:bold;">Carbon 版 Eclipse は遅かった。とてつもなく遅かった</span></p>
</blockquote>
<p>素の Eclipse に Plugin として TruStudio をインストールしても状況は改善されず、必然的に Emacs から Textmate へとテキストエディタを中心に開発環境は変遷し、Eclipse のコトは記憶の彼方に忘れ去ってしまいました。</p>
<br>

<h4> 再会もやはり不幸だった</h4>
<p>3年ほど前に愛機を PowerBook G4 から ThinkPad (T23 → R40e → X200 → T500) に変えました。</p>
<p>Snow Leopard の発表を機に OSX に幻滅した私は、以前から憧れを感じていた「タイルウインドウマネージャを駆使する Linux」に移行したのです。ディストリビューションは、もちろん(笑) Gentoo/Linux。</p>
<p>そんな中、GAE/J のデビューもあって Eclipse と二度目の邂逅を果たします。さすがに、GTK+ ベースであれば、Carbon 版のような不幸は起きないだろう、と高を括っておりました。確かに最初は幸福でした。</p>
<p>しかし...</p>
<blockquote>
<p><span style="font-weight:bold;">ファイル数が増えると、時が経過すると、徐々に遅くなって、最後はキー入力さえ遅延してしまう</span></p>
</blockquote>
<p>Gentoo 使いとしての私のスキルの低さも影響したと思うのですが、「何とまぁ。こうまで相性が良くないのか」と苦笑いする他ありませんでした。</p>
<br>

<h4> 三度目の出会いや如何に？</h4>
<p>2011年も明けた早々、2年ほど前に書かれた下記記事を発見しました。</p>

<ul>
<li> <a href="http://d.hatena.ne.jp/Yamashiro0217/20090616/1245121197" target="_blank">全Eclipse Java プログラマーに捧げる Eclispe 徹底活用術完全版〜Eclipseに空気を読ませて楽する術〜 - Yamashiro0217の日記</a></li>
</ul>
<p>Eclipse をまともに使いこなしたコトが無い私から見ると、恥ずかしながら、とても魅力的な内容でした。</p>
<p>丁度、MacBookAir Late2010 の魅力に勝てず、Gentoo/Linux からの移行を終えたばかりのころでしたが、Cocoa 版 Eclipse が存在していることを思い出した私は、チュートリアルがてら上記記事を試してみたのです。</p>
<p>すると...</p>
<blockquote>
<p><span style="font-weight:bold;">何ということでしょう！まるで、テキストエディタのごとく軽快に動作するではありませんか！</span></p>
</blockquote>
<p>上記記事の内容もさることながら、Cocoa 版 Eclipse 素晴らしさに感銘を受けました。以来、常用ツールとして、とても重宝しています。</p>
<br>

<h4> 静的な型付け言語こそが生産性向上のカギ？</h4>
<p>私の少ない経験ではありますが、PHP ⇒ Ruby ⇒ Python と、LL言語を変遷してきた中で感じたのは「LL言語は、世間が言うほど簡単ではない」ということでしょうか。特に オブジェクト指向の皮を被った Lisp であるところの Ruby は、私にとっては難しい部類の言語でした。</p>
<p>確かに、LL言語の場合は、学習開始前までの敷居が低いことは事実だと思います。しかし、いつまでも初心者ではいられません。チュートリアルとは比べものにならないほど規模が大きくなる開発で活用していくためには、言語仕様の学習もさることながら、言語実装以外の周辺環境が重要になってきます。</p>
<br>

<h5> 1. デバッガ</h5>
<p>まず、一番悩まされるのは変数の扱いでしょうか。LL言語であっても、デバッグの際は変数をトレースすることになります。しかし、その割に良いデバッガには、なかなかに巡り合いませんね。</p>
<p>変数の中身が見えてくると実装に内在する問題がググっと浮き上がってくるというのは、プログラミングに共通の出来事でしょう。Django のバックトレース画面には随分と助けられましたが、ああいう機能を標準で備えている方が例外です。</p>
<p>余談ですが、Erlang の変数には衝撃を覚えましたが、今はあのスタイルが一番良いのではないか、と思っています。</p>
<br>

<h5> 2. 補完機能</h5>
<p>最近の LL言語であれば、ライブラリについてはまったく問題無いでしょう。むしろ重量級が多く、必要な API を覚えるだけでも一苦労です。</p>
<p>そこで、補完機能を備えた支援システムがクローズアップされることになるのですが、LL言語ではこの時点で一定の限界に到達するように思います。</p>
<p>インストール方法が複雑かつ、それでいて動作も完全に保証されている訳ではありませんので、時間を掛けてセットアップした割に動かなかった、ということは日常茶飯事です。趣味ならばともかく、仕事で使う場合は「えっ...」と絶句する瞬間ですね (苦笑</p>
<br>

<p>わずか二つの事例だけで優劣を論じるのは少し無理があるようにも思われますが、Eclipse などの導入しやすい IDE 文化が中心にある java には一日の長があるのでしょう。良くも悪くも、エンタープライズ市場で鍛えられてきた環境は伊達ではないのでしょう。</p>
<blockquote>
<p>静的言語が一方的に効率が悪いとされた時代は過ぎたのではないか</p>
<p><a href="http://d.hatena.ne.jp/shuji_w6e/20110306/1299419445" target="_blank">76-コード分析ツールを利用する - やさしいデスマーチ</a></p>
</blockquote>
<p>最近は、空気を読んでくれる Eclipse と相まって、java を見直す日々であります。</p>
<p>いよいよ言語仕様も古くなってきて、「いつまで使えるか？ Oracle で大丈夫なのか？」などなど、その将来に多くの人が疑問符を持つ状況になっているようにも思いますが、さりとて、その代替となると、これまでの資産の継承も含めて完全にリプレース可能なキラー言語に淘汰されるのは、もうちょっと先でしょう。</p>
<p>個人的には、Scala をもうちょっとスリムにした、Eclipse 上で安定したプラグインが供給された、静的な型付けの関数型言語が登場しれくれれば、一番嬉しいです。</p>
<p>そんな夢のような日まで、java とお付き合いする日々が、どうやら続きそうです。</p>
</div>
]]></content:encoded>
<dc:creator>ayu_standalone</dc:creator>
<dc:date>2011-03-08T17:34:57+09:00</dc:date>
<dc:subject>eclipse</dc:subject>
</item>
</rdf:RDF>

