Clojureの最近のブログ記事

CTO「深町さん、Clojureの記事を書きませんか」

 と井上さんに言われたのはもう4ヶ月も前のことです。WEB+DB PRESSの特集「Scala & ClojureではじめるJVM言語」をアリエルで書くことになり、僕にそのClojureの章を担当してもらえないかという話でした。

 その頃僕は、SoftwareDesignで二度、Emacsの記事を書いていてとてもうんざりしていました。そして、「もうLispの原稿以外は書かない」と決めた矢先のことです。

 Clojureと言えばLispじゃないですか。それなら書いてもいいかも…。いや…。

僕「何を書けばいいんですか?」

 ここは慎重になるべきです。

CTO「まだ詳細は決まっていませんが、DSLかWeb系か」

 LispでDSLと言えば……マクロ……!!!

僕「最近ClojureでL5というプレゼンツールを作ったんですが、その話なら」
CTO「じゃあそれでいいです。」

 なんと雑誌でLispの、しかもマクロの記事が書けるなんて思いもしませんでした。さらにL5の宣伝ができるなら原稿を書くのも耐えられるというものです。

僕「どういった視点で書けばいいですか? たとえば、Lispは知っている前提でいいのか、lambdaは知っている前提でいいのか、マクロは知っている前提でいいのか」
@liris「ハードル高っ」

Lispを知らないJavaプログラマ向けでお願いします

 もうこれは絶望です。JavaプログラマにLispを一から、しかもたったの8ページで説明するなんて無謀です。無謀過ぎます。

僕「……さすがに無名関数は知ってる前提で構いませんよね?」
「いや、できれば知らない前提で」


 ……。


いちからか? いちからせつめいしないとだめか?


 Javaプログラマとは言えWEB+DB PRESSを購読しているような人たちが無名関数の存在を知らないとか考えづらいのですが、まあそういう要求であれば仕方がありません。そして必死に考えた末、ひとつの結論に行き着きました。

 僕がLispを始めるきっかけとなった「ハッカーと画家」は、Lispの細々とした話は出てきません。一からLispの文法の説明をしたところでLispの魅力は伝わらない。重要なのは「Lispをやってみたい!」と思わせること。であればPaulのように、ひたすらLispはすごいんだぜという論調で書こう、と。

 なのでClojureの”入門記事”というよりも”紹介記事”と言ったほうがいいかもしれません。


@liris「深町さん、Java嫌いそうですよね」
僕「え、でもdisり要素はいれてないはずですが…」
@liris「行間に漂ってますよ」


 WEB+DB PRESS Vol.61は2月24日に出ます。行間に漂うLisp最強オーラを感じていただければ幸いです。


L5のver1.2.0をリリースしました

| 【5分で読めるよ!】 | コメント(0) | トラックバック(0)

 今日はクリスマスイブですね。みなさんご存知の通り、今年も事業仕分けによって引き続きクリスマスが中止になってしまったので、プログラマな人たちは各地でハッカソンでもして楽しく過ごしましょうね。

 今日はそんなプログラマたちのためにL5のver1.2.0をリリースしました。

※追記(2011/01/11): ver1.2.1をリリースしました。

インストール

 GitHubからL5.jarをダウンロードしてください。

 あとはダブルクリック(or java -jar L5.jar)で起動するだけです。

使い方

GUIでの利用

 起動すると以下のようなメインウィンドウが表示されます。

l5-v120-create-button.png


  • Create … プレゼン資料のテンプレートを生成
  • Open … 既存のプレゼン資料からプレゼンをスタート


 「Create」を押すとファイル選択画面が表示されるので、テンプレートの保存場所を指定してください(例: hoge.clj)。

 テンプレートの内容は以下のようになっています。

(ns L5.presentation
  (:use L5 L5.layout))

(defcontext
  {:width 640 :height 480
   :font-family "Gill Sans"
   :font-size 30})

(defslides
  ;; Title page
  [(t "タイトルを入力")
   (with {:font-size 15
          :position :fixed
          :padding {:top 360}}
     (lines "アリエル・ネットワーク"
            "深町英太郎"))]
  ;; Itemize slide
  [(title "タイトルを入力")
   (item "箇条書き1"
         "箇条書き2")]
  ;; Extra large letters
  [(t "入力")])

(start)

 ここから資料を作る場合は(defslides ...)の部分を編集してください。


 作った資料を開くにはメインウィンドウで「Open」をクリックし、資料のファイルを選択します。

l5-v120-presen-window.png

コマンドラインからの利用

 もちろんのことですが、L5はコマンドラインからのプレゼンの実行もサポートしています。L5を起動するとき、単純にコマンドライン引数としてファイルを指定すると、直接プレゼンテーションを開始できます。

$ java -jar L5.jar sample/lisp-poetry.clj

 また、今回からプレゼン資料をスクリプトとして実行することもできるようになりました。上でダウンロードしたL5.jarをCLASSPATHの通ったところに置いておけば、プレゼン資料をClojureスクリプトとして実行することができるようになります。

$ clj sample/lisp-poetry.clj

キーバインド

 プレゼンを実行中はキーボードでプレゼンを操作します。

  • 次のページ … <Right>, <Space>, <Return>
  • 前のページ … <Left>, <Backspace>
  • フルスクリーンをトグル … <F5>
  • フルスクリーンを解除 … <Esc>
  • プレゼンをリロード … <R>
  • プレゼン終了 … <Q>
  • プレゼンをPDFで出力 … <E>

 プレゼンをスタートして、修正→リロード、修正→リロード、というサイクルを繰り返して資料を作ります。

 また、PDFでの出力をサポートしているので、発表後にSlideShareにあげたりするのも簡単です。

まとめ

 以上、僕からのクリスマスプレゼントでした。

 何か問題や要望があったら僕にGitHubTwitterで報告してください。日本語で大丈夫です。

 昨日、トイザらスに行ったら街中のサンタさんが買い出しをしていました。こんなにサンタさんがいるなら、一人くらい僕にプレゼントをくれてもいいんじゃないでしょうか。サンタさん、僕にAllegro CLライセンスをください。

v1.2.0の変更点まとめ

バグ修正

  • :text-align, :vertical-alignのパディングがおかしかった問題 (#35)
  • :colorが動いてない問題 (#21)
  • linesにpadding topを指定しても反映されない問題 (#17)
  • PDFのエクスポート時にプログレスバーもキャプチャされることがある (#27)

新機能

  • フルスクリーンのマルチディスプレイ対応 (#24)
  • <Q>でプレゼンを終了できるように (#26)
  • プレゼンのテンプレート生成機能(“Create”ボタン) (#32)
  • defcontextがない場合にエラーにしない
  • <R>でコンテキストもリロードできるようにした
  • スクリプトとしてプレゼンを実行できる

L5のver1.1.0をリリースしました

| 【6分で読めるよ!】 | コメント(0) | トラックバック(0)
※重要 この記事は古いです。新しいバージョンに移動する

 今日は秋分の日ですね。今日から秋なので、ちょっと秋らしいことをしようかなと思いました。

「秋…。秋か…。秋といえば、プログラムの秋…」

 ということでL5のver1.1.0をリリースしました。

前バージョンとの違い

  • スライドの記述言語が少し簡単になりました
  • GUIで操作できるようになりました
  • UbuntuでPDFエクスポートができない問題を解決しました

使い方

 L5はJDKがインストールされている環境なら動きます。以下のリンクからJARファイルをダウンロードしてください。

 JARファイルはダブルクリックで起動できます。たぶんね。できなかったらごめんなさい。コンソールで$ java -jar L5.jarしてください。

 起動すると以下のようなパネルが開きます。

L5-main-window.png

 「Open」をクリックしてL5のプレゼンファイルを選択すればプレゼンテーションが始まります。

 どんな感じの表示になるかを確認したければ、サンプルからcljファイルをダウンロードしてOpenしてみてください。

L5-sample1.png

L5-sample2.png

プレゼン資料を作る

構成

 プレゼン資料は以下のような構成になります。

(ns L5.sample
  (:use L5 L5.layout))

(defcontext {...})

(defslides [...]*)

 defcontextは”コンテキスト”の設定、defslidesはスライドの記述です。

コンテキストの記述

 L5では資料全体に影響するパラメータを”コンテキスト”と呼びます。コンテキストの定義にはdefcontextを使います。たとえばこんな感じ。

(defcontext
  {:width 640  ; 横幅
   :height 480  ; 縦幅
   :font-family "Gill Sans"  ; フォント
   :font-size 30  ; 文字の大きさ
   :color (Color/white)  ; 文字の色
   :background-color Color/darkGray  ; 背景の色
   })

 他に:background-imageも指定できます。

スライドの記述

 スライドはdefslidesで定義できます。たとえば。

(defslides
  [(title "自己紹介")
   (item "深町英太郎です"
         "Webプログラマ"
         "Lisper (CL, Clojure)"
         "Perl5, JavaScript..."
         "オープンソース愛好家")]
  ...)

 スライド一つは[...]で表します。

 スライドは複数の”要素”を含みます。この要素は文字とか、画像とかです。上の例では(title...)(item...)の2つの要素が入ったスライドを作っています。

title[& strs]スライドの上部にタイトル文字をつける
lines[& strs]文字を一行ずつ表示
item[& strs]文字を箇条書きで一行ずつ表示
enum[& strs]文字を行番号をつけて一行ずつ表示
t[& strs]画面いっぱいの文字を表示 (高橋メソッド)
img[file]指定された画像ファイルを表示 (相対パス)

 これらは要素を記述するものですが、その他にレイアウト用のマクロもあります。

with-size[size & body]中の要素の文字サイズを変更
with-padding[padding & body]中の要素のpaddingを変更
with[params & body]中の要素のパラメータを変更 (より汎用的なマクロ)

より詳しく知りたい人のために

 この節は蛇足なので読まないでいいです。

 ver1.1.0では、前バージョンにあったalignなどのマクロがなくなっていますが、文字の整列ができないわけではありません。実際、(title..)はセンタライズされて表示されます。

 実はスライドの各要素はdefslidesに渡される段階で最終的にArrayMapになっており、これが描画する関数に渡されてスライドが構築されます。上の例だけ見ればtitleなどを使って描画しているように見えますが、これはただArrayMapを返すマクロです。なのでdefslidesに以下のように書いても同じです。

(defslides
  [{:attr {:text-align :center
           :padding {:bottom 20}}
    :body "自己紹介"}
   {:attr {:padding {:top 10 :bottom 10}}
    :body ["深町英太郎です"
           "Webプログラマ"
           "Lisper (CL, Clojure)"
           "Perl5, JavaScript..."
           "オープンソース愛好家"]}]
  ...)

 各要素は:attr:bodyのキーを持つArrayMapです。:attr:text-align :centerと指定すると文字をセンタライズできます。

 上で紹介したwith-*系のマクロは、この要素の:attrをいじるための構文糖でしかありません。

キー操作

進む→、Space、Enter
戻る←、BackSpace
フルスクリーンF5 (トグル)、Esc (解除)
リロードR
PDF出力E

まとめ

 L5も随分と使い勝手がよくなったように思います。まだKeynoteにはかないませんが、LT資料をサクッと作る程度なら十分な手軽さになっています。

 ぜひプレゼンの秋に活用してみてください。

S式で書くプレゼンツール「L5」をリリースしました

| 【8分で読めるよ!】 | コメント(0) | トラックバック(0)
※重要 この記事は古いです。新しいバージョンに移動する

 以前公開したS式で書くプレゼンツール「L5」の続報です。

 公開時と比べるとプレゼンを書くためのマクロの整備と、それに伴った機能拡張がされています。今まではほとんど自分一人が使うために開発を続けていましたが、既に実用レベルに達していると感じる完成度になったためver1.0.0として正式リリースすることにしました。

http://github.com/fukamachi/L5/tree/1.0.0

 1.0.1をリリースしました。

http://github.com/fukamachi/L5/tree/1.0.1

セットアップ

 L5を使うにはLeiningenというClojureのビルドツールが必要です。

※Clojure本体のインストールは必要ありません。Leiningenが勝手にダウンロードします。

Leiningen

 まずはLeiningenの最新安定版(1.3.0)を導入します。

$ sudo wget -O /usr/local/bin/lein http://github.com/technomancy/leiningen/raw/1.3.0/bin/lein
$ sudo chmod a+x /usr/local/bin/lein
$ lein self-install

※先日 @peccul さんから、L5のビルドが途中で止まってしまうという現象が報告されました。原因を探ると、Leiningen 1.3.0からのバグが原因のようです。このバグにはL5側が回避するような修正をしたため、現在はLeiningenによる不具合は改善されています。

L5

 L5の導入は簡単です。gitが入っていない場合はDownloadsからtgz/zipをダウンロードできます。

$ git clone git://github.com/fukamachi/L5
$ cd L5
$ git checkout refs/tags/1.0.1
$ lein deps

 これでセットアップが完了です。ここで、以下のコマンドを実行するとサンプルのプレゼンテーションが起動します。

$ lein run presen

チュートリアル

下準備

 L5を起動すると、L5のディレクトリルートにある run.clj というファイルが実行されます。この実行ファイルでは以下の2つを定義します。

  • コンテキスト (フレームの大きさ、文字の色など)
  • スライド

 デフォルトのrun.cljには以下のように書いてあります。

;; Delete this line and write your slides below.
(load-file "sample.clj")

 これはsample.cljをロードするだけのコードで、プレゼンの記述はsample.cljに書かれています。

 新しいプレゼンテーションは、コメント通りにまずrun.cljの2行を削除してから始めます。

 その後、以下のように名前空間を定義します。名前空間の名前は何にしても構いません。

(ns L5.sample
  (:use L5 L5.layout))

 これで準備完了です。

コンテキスト

 次にコンテキストを定義します。コンテキスト定義にはdefcontextを使います。

(defcotext {...})

 以下は640x480のフレームで、フォントは「Gill Sans」の30ptを指定しています。

(defcontext
  {:width 640 :height 480
   :font (Font. "Gill Sans" 0 30)})

 コンテキストには主に以下のパラメータがあります。

color文字色 (Colorオブジェクト)
background-color文字色 (Colorオブジェクト)
background-image背景画像 (ImageIOオブジェクト)
widthスライドの横幅
heightスライドの縦幅
paddingパディングをMapで指定 (例: {:top 100 :right 20 :bottom 100 :left 20})
fontフォント (Fontオブジェクト)

 これらはスライド内で適宜変更することができます。詳細は次節で説明します。

スライド

 次はいよいよスライドを作ります。スライドはdefslidesで定義します。

(defslides slide-functions*)

 例を出します。

(defslides
  (p (with-title "自己紹介"
       (item "深町英太郎です"
               "Webプログラマ"
               "Lisper (CL, Clojure)"
               "Perl5, JavaScript..."
               "オープンソース愛好家"))))

 ここで、pはpageを表しています。このスライドは item の中身の文字列を一行ずつ箇条書きで表示するスライドです。

Screenshot.png

 ここで使用できる主なAPIは以下の通りです。

  • レイアウト関連
p[& body]ページ
title-page[& strs]表紙用の整列された大きな文字を表示
with[params & body]一時的にcontextのパラメータを上書きして実行
with-size[size & body]一時的にコンテキストのサイズを変更
with-padding[padding & body]上を指定ピクセルだけ空けて表示
with-title[title & body]上部にタイトルをつけたレイアウト
  • 文字関連
lines[& strs]引数の文字列を一行ずつ表示
item[& strs]引数の文字列のそれぞれの行の先頭に”・”をつけて表示 (itemizeの略)
enum[& strs]引数の文字列のそれぞれの行の先頭に行番号をつけて表示 (enumerateの略)
align[align & strs]文字列をセンタライズして表示
t[& strs]引数の文字列を画面いっぱいに表示 (Takahashiの略)
img[file]指定されたファイル名の画像を表示
fit[& strs]表示領域いっぱいに文字列を表示
txt[& strs]必要に応じて文字を折り返して表示

実行時リロード

 スライドを書いたら、L5のルートでlein run presenを実行して起動できます。ただ、スライドを一部変更したときにいちいちL5を再起動するのは面倒です。

 L5にはスライドのホットリロード機能があり、[R]キーを押すだけで再起動せずにエディタで書いたスライドの内容を反映することができます。

キー操作

次のページ: [Right]、[Enter]、[Space] 前のページ: [Left]、[Backspace] フルスクリーン: [F5] (トグル)、[Esc] (解除) ホットリロード: [R]

PDF出力

 L5には書いたスライドをPDFとして出力する機能があります。L5のルートディレクトリで以下のコマンドを実行してください。

 $ lein run export

 少し待つと同じディレクトリに”output.pdf”というファイルが出力されます。

開発状況

 見ての通りGitHubでオープンソースとして公開しています。BTSにはGitHub付属のIssuesを利用しています。

L5の未来

 あまり新しいソフトウェアの未来を語るとあとで恥ずかしいことになりそうですが、少しだけ。

 L5の設計思想は「自分に合わせたプレゼンツールを設計できる」というものです。S式とマクロによる抽象化で、自分のプレゼンスタイルに合わせたDSLを構築することができます。これは今後も続けていく方針です。

 また、将来的には完成度として劣らないプレゼンテーションを作れるようにしたいです。Keynoteは美しさの面で非常に素晴らしいツールです。L5はそういった「美しさ」も劣らないソフトウェアとして改善していこうと思います。

L5が実行時にスライドを逐次更新できるようになりました

| 【1分で読めるよ!】 | コメント(0) | トラックバック(0)
※重要 この記事は古いです。新しいバージョンに移動する

 つい先日、L5というプレゼンツールを公開しました。

 ただ、公開したとはいえ、L5はまだ開発が続いています。今日、新機能を2つほどつけたので紹介します。

新機能1 ホットリローディング

 今まではテキストエディタでスライドを書いて、一度プレゼンの画面を確認したいと思ったときは、L5自体を再起動するしかありませんでした。それもすぐに起動してくれるならいいのですが、何せClojureなので再起動に時間がかかってしまいます。

 そこで、L5自体を再起動させずに、実行時にスライドを再読み込みする機能をつけました。使い方はフレームで「R」キーを押すだけです。試してみてください。

 そのうち「R」を押すのすら面倒になったら自動リロードに変わるかもしれません。

新機能2 実行中のL5にアクセス

 こちらは実装する気はなかったのですが、デバッグに楽だったのでつけました。

 まず、L5を別のターミナルで起動させておきます。

$ nc localhost 12345 25
clojure.core=> (ns L5.core)
nil
L5.core=> @(:current @*context*)
0

 上記のように実行中のL5にREPLでアクセスできます。用途はたぶんデバッグ以外ありません。デバッグが好きな人は試してみてください。

意見や報告や要望をください

 もし使ってみた人がいれば意見や要望をください。GitHub付属のIssuesか、Twitterに日本語か英語かS式でコメントしてくれたら返信します。

S式で書くプレゼンツール「L5」を作りました

| 【4分で読めるよ!】 | コメント(0) | トラックバック(0)
※重要 この記事は古いです。新しいバージョンに移動する

 夏ですね。夏といえばオープンソースの季節です。みんなオープンソースしていますか? 僕は風邪を引いています。

「うぅ、苦しい。死ぬ。僕が死んだら僕のGitHubに残されたオープンソースプロジェクトたちを頼む……」

 えっと、新しくS式で書くプレゼンツールの「L5」を公開しました。

http://github.com/fukamachi/L5

「L5」って何?

 「L5」はLisperによるLisperのためのプレゼンテーションツールです。S式でスライドを記述し、スライドショーを表示します。

 たとえばこんな感じ。

(p (with-title "自己紹介"
       (item "深町英太郎です"
             "Webプログラマ"
             "Lisper (CL, Clojure)"
             "Perl5, JavaScript..."
             "オープンソース愛好家")))

 pはページを表していて、with-titleで上の表題、itemが箇条書きを表しています。

 スライドショーではこんな感じになります。

Screenshot.png

 本体はClojureで実装されており、ここの中ではすべてのClojureコードが使えます。これは既存のAPIを使って自分の好きなようにマクロでラップできるということです。この透過性はLisperにとって天国になりえるでしょう。L5はLisperのためのプレゼンツールです。

なぜ新しく作ったの?

 名前の由来は言うまでもなく、amachangさんの「S6」(前バージョンはS5)です。S6はJavaScriptとHTMLで記述できるプレゼンツールで、PowerPointのようなGUIのプレゼンツールを好まない技術者層によく使われています。テキストエディタでも気軽に書けるプレゼンツールという点ではL5もS6と同じです。

 テキストベースのプレゼンツールは他にもあります。けれど、構文が複雑だったりおまじないコードが多かったり、ものによっては簡潔さのためにパワー不足になっているものもあります。

 これらはマクロを持つLispがもっとも得意とする分野です。僕は自由度が高く簡潔な構文を持つ(またそれを自分で定義できる)プレゼンツールが欲しかったのです。

インストール

 あらかじめLeiningenがセットアップされていることを確認してください。(Clojure本体は必要ないかも?)

$ git clone git://github.com/fukamachi/L5
$ cd L5
$ lein deps

使い方

 L5はLeiningenのプラグインの一つである、lein-runを使っています。これはローカルアプリケーション用にターミナルからLeiningenプロジェクトを起動できるプラグインです。

 プレゼンを始めるには以下のコマンドを実行します。

$ lein run presen

 ソースを何も変更しない状態ではサンプルのプレゼンテーションが始まります。サンプルというか、アリエルの社内で発表したClojure勉強会の資料です。せっかくなので読んでみてください。

 起動してタイトルが表示されたら起動完了です。その後は矢印の左・右でスライドをいったりきたりできます。

 また、F5キーを押すとフルスクリーンモードに切り替わります。

記述方法

 lein run presenが実行されると、プロジェクトルートにあるinit.cljというファイルがロードされます。基本的にこのファイルを変更すればプレゼンを記述できます。デフォルトではsample.cljをロードするだけのコードです。

 L5は現在活発に開発が行われているので、APIはすぐに変わってしまうかもしれません。けれど現状のAPIはコードを読む人にとっても何らかのヒントになると思うので書いておきます。

  • p - ページ
  • with - contextのパラメータを変更して表示
  • item - 箇条書き(前置記号”・”)
  • lines - 一行ごとに記述
  • th - 内容をページ全体に最大化(TakaHashiの略)

 基本的にはこれくらいですが、他にいくつか便利なエイリアスがあるので、調べたい人はlayout.cljを見てください。

PDFへの出力

 プレゼンツールにPDF出力は欲しいです。まだ実装したてなので安定しませんが、L5にはPDFへのエクスポート機能が実装されています。

$ lein run export

 少し時間がかかるのですが、これを実行するとスライドの内容がoutput.pdfという名前で出力されます。

 ただ、さっきUbuntuで試してみるとスライドが大幅にずれていました。Javaの「Write once, run anywhere」にだまされた感じです。そのうち対応するのでそれまでお待ちください。Macでは正常に動くはずです。

 output.pdf [SlideShare]

ロードマップ

 L5は未完成の代物です。現状でも足りないと思える機能がいくつも思い当たります。

  • 画像や動画を埋め込めるようにする
  • スライドショー中に変更した記述をリロードできる機構を用意
  • スライドショー中にコンソールに次のスライドの内容を表示
  • 独立したJARファイルにしてポータビリティを増す
  • Twitterハッシュタグとの連携
  • アニメーション
  • スライドの美しさ

まとめ

 勉強会で発表することがあれば、プレゼンツールは数ヶ月に一回は使うものです。その長さは30分だったり5分だったり。レイアウトもさまざまだったり。

 プレゼンツールに自分を合わせるのではなく、自分に合うプレゼンツールに仕立てられるツールにしていきたいです。

appengine-cljにURLFetch APIを追加しました

| 【1分で読めるよ!】 | コメント(0) | トラックバック(0)

 どうやらゴールデンウィークも今日までらしいですねっ。先日の記事では広島から更新しましたが、本日無事に関東に戻ってきました。今はリナカフェにいます。

 appengine-cljをフォークして先日Memcache APIを追加しましたが、今度はURLFetch APIを追加しました。

fukamachi’s appengine-clj at master - GitHub

 そもそもページをfetchするしか機能がないのでREADMEで十分かもしれませんが、一応使い方などをまとめておきます。

使い方

(use 'appengine.urlfetch)

(fetch "http://www.google.com/")

レスポンス

 fetchの返り値は以下のようなMapです。

{:status-code 200
 :headers {:Content-Type "text/html; charset=utf8", ...}
 :content ".."}

複雑なHTTPリクエスト

 fetchはいくつかのオプションを受け取ることができます。オプションは第2引数にMapで指定します。

(fetch "http://www.google.com/" {:method "POST", :follow-redirects false})

 サポートされているオプションは以下のものです。

  • method (デフォルトでGET)
  • payload
  • headers (Mapで指定)
  • allow-truncate
  • follow-redirects (デフォルトでtrue)

インストール

 project.cljの:dependenciesに以下を追加してください。

[org.clojars.fukamachi/appengine "0.1.1"]

 そしてlein deps。対応Clojureバージョンは1.1.0です。

どう?

 深町フォークを使ってみたくなりましたか? :) この調子でTaskQueueやMailなどのAPIも随時追加していきたいと思っています。もちろん、pull requestも歓迎です。

appengine-cljにMemcache APIを追加しました

| 【2分で読めるよ!】 | コメント(0) | トラックバック(0)

 ゴールデンウィークですね。皆さんはどこかに行くんでしょうか。僕は広島でプログラムを書いてます。

 AppEngineとClojureでプログラムでも書こうかと思ったのですが、ClojureのAppEngineのAPIラッパーがありませんでした。いや、ないわけじゃないんですが、Memcacheのラッパーがありませんでした。appengine-cljは名前ばっか汎用的なくせしてDatastoreしかサポートしてないようです。僕が欲しいのはMemcacheのラッパーなのです。

 OSSだしfolkすればいいんじゃねってことでappengine.memcacheを追加したので紹介します。

fukamachi’s appengine-clj at master - GitHub

使い方

とりあえずputしてget

(use 'appengine.memcache)

(put-value "count" 1)
(get-value "count") ;;=> 1
(delete-value "count")

 ただ値を(イン|デ)クリメントするだけならinc-valuedec-valueが使えます。

(inc-value "count") ;;=> 2
(dec-value "count") ;;=> 1
(inc-value "count" 10) ;;=> 11

セットポリシーを指定

 ただ追加するだけならput-valueを使えばいいですが、場合によっては既にないときだけセットしたいときもあります。いや、僕はないですが、ある人もいるみたいです。

(if (not (get-value "count")) (put-value "count"))

 こういう用途のためにMemcacheサービスにはセットポリシーという機能があります。

(add-value "count" 1) ;; まだないときだけセット
(replace-value "count" 1) ;; (上と逆に)あるときだけセット
(set-value "count" 1) ;; あってもなくてもセット (put-valueと同じ)

期限を設定

 上の例ではキャッシュの削除期限を指定していませんでした。指定しない場合はできるだけ長く記録され、容量があふれたりしたときに自動で削除されます。ただ、期限を指定したいときもありますね。僕はあります。appengine-clj.memcacheを使えば期限の指定も簡単です。

;; 第3引数に秒数を指定
;; 1日後に削除
(put-value "age" 22 86400)

 削除する日付を指定したい場合はjava.util.Dateを使います。ちょっといけてない気もしますが、まあいいよね。

;; 2010/10/3に削除
(put-value "age" 22 (java.util.Date. 110 10 3))

 ただ、あんまり遠い未来にしても、所詮Memcacheなので期限前に消える可能性もあるのでそれに依存したコードは注意です。

今後

 appengine-cljはGitHub上で、もはや作者の手を離れていろんな人にfolkされまくってます。僕もその自由さにつけこんで深町ブランチとしてちょこちょこコミットしていこうと思います。

 ちなみに僕はこれから島根に行きます。

「え、Matzさんに会いにいくの?」

 違います。ただのお墓参りです。小川さんの家にも行きません。ちなみにお墓は古墳ではありません。Matzさんのお墓でもありません。普通のお墓です。つまり島根プログラミングなのです。

AppEngineのDatastoreにはclj-gae-dsを使え

| 【6分で読めるよ!】 | コメント(0) | トラックバック(0)

 Shiroさんの翻訳プログラミングClojureが発売されたこともあって、この前のShibuya.lispではClojure祭りでしたね。

 先日、Tokyo.cljの記念すべき第1回「Clojure Hackason」も開催されました。主催者は @masa_edw さんです。しかも定期的に月1ペースでハッカソンを開催するそうです。すごいですね。

 さらに日本でClojureを流行らせようと、@making さんが clojure-users.org というサイトも運営されています。なかなかすごいバイタリティです。

 これは、ひょっとして、今まさに空前のClojureブームなのではないか!




bigwave1.jpg




 そこで僕は何をやるのか。僕はご存知のようにWeb屋なので、Webアプリケーションを作ることに興味があります。ClojureでWebアプリケーション、とくれば、もちろんGoogle AppEngineですね。

 今日は、 @making さん作の、DatastoreのClojureラッパー、「clj-gae-ds」をいじってみたので紹介したいと思います。

「何言ってんだドク、日本製は最高なんだぜ」

 ClojureのAppEngine用のラッパーと言えばappengine-cljがあります。ただこのライブラリは一部欠けた部分があって、結局AppEngineのJava APIを叩かないといけないとかで面倒な部分もあります。

 その点clj-gae-dsはきれいにラップされてますし、まあ、なにより日本製ですしね。Made in makingですしね。日本のClojurianはみんな使うといいです。

Entityを挿入・更新

 RDBMSではデータ一つ一つをRowとかRecordとか言いますが、DatastoreではEntityと言います。まずはmap-entityを使って挿入するEntityを作ります。

(map-entity "kind" :prop1 "value" :prop2 "value")

 DatastoreではテーブルのことをKindと言います。これを使って以下のようにEntityを作ります。

(def luffy (map-entity "person" :name "Monkey D. Luffy"))

 Datastoreはスキーマレスなので、Entityに好きなPropertyをつけることができます。

(def luffy (map-entity "person" :name "Monkey D. Luffy" :ability "GomGom" :bounty 100000000))

 もしPropertyの値を取得/変更したい場合はget-prop / set-propを使います。

(get-prop luffy :name) ;;=> "Monkey D. Luffy"
(set-prop luffy :bounty 300000000) ;; 懸賞金が1億→3億に

 このEntityはまだDatastoreに保存されていません。これを実際にDatastoreに入れるにはds-putを使います。

(ds-put luffy)

 あんまり使わないかもしれないですが、返り値はKeyオブジェクトです。

DatastoreからEntityを検索・取得

 挿入する際はEntityというオブジェクトを介しましたが、逆にデータを取り出したいときはQueryというオブジェクトを作らないといけません。

 以下は”person”からすべてのデータを取り出すQueryです。

(query "person")

 もし、取り出すデータに条件をつけたい場合はadd-filterを使います。

(add-filter (query "person") "ability" :eq "Santoryu")

(追記) Property名はstringです。keywordじゃありません。気をつけてください。僕も気をつけます。

(追記) Property名がkeywordにも対応したそうです。仕事早いです。以下で出てくるadd-sortもstring / keywordの両方使えます。

 比較演算子にはキーワード形式で :eq, :neq, :lt, :gt, :lte, :gte, :in 、もしくは 関数形式で =, not=, >, >=, <, <= を使えるようです。これはappengine-cljに対してかなり便利な機能だと思います。

 さらにこのQueryからEntityを取り出すには query-seq を使います。これは、クエリを受け取ってLazySeqを返してくれる便利な関数です。

;; 三刀流のメンバーは誰?
(let [q (add-filter (query "person") "ability" :eq "Santoryu")]
  (first (query-seq q)))

 結果をソートしたい場合はadd-sortを使います。

;; 懸賞金が高い順に3人取得
(let [q (add-sort (query "person") "bounty" :desc)]
  (take 3 (query-seq q)))

 ただ結果に含まれるEntity数だけを知りたい場合はcount-entitiesが使えます。

;; 女性メンバーは何人?
(let [q (add-filter (query "person") "sex" :eq "female")]
  (count-entities q))

Entityの削除

 Datastoreの削除はパフォーマンス上好ましくないですが、必要な場合もあるでしょう。Entityの削除はds-deleteで行います。

 注意すべきなのが、このds-deleteの引数はKeyオブジェクトということです。Entityではありません。EntityからKeyを取り出すには (.getKey entity) する必要があります。

(ds-delete (.getKey usopp))

EntityをMapに変換

 他に、EntityをMapに変換してくれるentity-map もあります。map-entityではありません。ややこしいですね。これは関数名を entity->map に改めるべきだと思いますが…

(entity-map nami)

まとめ

 他にもいくつか関数が提供されていますが、日常的に使うものは以上のもので十分っぽいです。

 clj-gae-dsはラッパーではありますが、EntityとかQueryとかKeyとか存在理由のわからないオブジェクトが出てくるのでDatastoreの知識がない人にはわかりづらいかもしれないですね。

Tokyo.clj#2 Clojure Hackasonの参加者募集中

 来月開催予定のTokyo.clj#2 Clojure Hackasonの参加者を募集中です。今見ると7人ほど空きがあります。ゴールデンウィークなので僕は参加できないかもですが、興味がある人はぜひ参加を。

→Clojure Hackasonに参加する

社内LTで「手嶋屋を愛する人たちへ」を発表しました

| 【10分で読めるよ!】 | コメント(0) | トラックバック(0)

 最近、手嶋屋内で「AB型こわい」という声が聞こえるたびに反応してしまいます。怖くないよ! 僕怖くないよ!

 AB型というとよく「あぁ、変人の」って言われますが、こわいって言われるのは初めてですね。もともと変な人の多い手嶋屋だから、ちょっとやそっと変でも目立たないのかもしれません。

僕「手嶋屋に変じゃない人っているんですか?」

 いないですよそんなの。僕以外。

 そんな手嶋屋で、今日も社内LTをやりました。

このアーカイブについて

このページには、過去に書かれたブログ記事のうちClojureカテゴリに属しているものが含まれています。

次のカテゴリはCommon Lispです。

Ariel Labs
Name:深町英太郎
Age:23歳
Living:京都府
Company:はてな
Hatena Id:id:nitro_idiot
Facebook:eitarow.fukamachi
mixi:ID:6756132
Twitter:nitro_idiot
GitHub:fukamachi
LinkedIn:eitarowfukamachi

最近のコメント

Techonrati

Technorati search

» リンクしているブログ

Powered by Movable Type 4.23-ja