日曜日, 5月 31, 2009

[Scala] GAE/JでJDO!

GoogleAppEngine/Javaではディスクが無いことからJDO/JPAでのデータ保存が必須です。

これをピュアScalaで(Javaクラスを使わず)やっている例題scalagaeを見つけたのだが、うまく動かず苦労。

原因は「java.lang.VerifyError」が出てしまうことだったのだが、これはJDO実装であるDataNucleusのバグである様子。v1.1.3に入れ替えたら無事に動きました。
具体的には、D:\appengine-java-sdk-1.2.1\lib\tools\ormにあるdatanucleus-enancer-1.1.0.jarが悪いのでdatanucleus-enhancer-1.1.3.jarに入れ替えます。

あと、コマンドラインからGAEにuploadするとき、app_idはscalagae\WEB-INF\appengine-web.xmlに書かれるので、適宜書き換えましょう。

土曜日, 5月 30, 2009

[Scala] GAE/J上でコンパイル!?

GAE/J上でコンパイル、JDOでバイトコードを保存、それを引き出して実行する、という機構を作ろうプロジェクトを見つけた。動くのかな。

金曜日, 5月 29, 2009

[Scala] PulpCore!

Javaの2DレンダライブラリであるPlupCoreのScala版があった。何故ソース的に焼き直したのかまったく不明。。

水曜日, 5月 27, 2009

[Scala] Rail@GAE/J!

JRubyがあるわけなので、出来そうではありますが、普通にありました。すごい。

ちなみに、Python版ではブログアプリ@GAEを見つけたのだが、これのJava版、もっというとScala版は無いものでしょうか。

日曜日, 5月 24, 2009

[Solr] WebService::Solrが

自前でSolrのレスポンスを、XML::Simple使って解析しようとして四苦八苦していたところ、、ふと思いついて調べてみたら、案の定WebService::Solrなるものが。。

早速書き直してみたところ、SolrのレスポンスのクセxXML::Simpleのクセにやられていた(例外処理ばかりだったコード)が、シンプルにんありました。

最初から調べておけば。。。

追伸:
XMLじゃなくJSONのレスポンスを解析してますね、、なるほどー。そういえば、確かにJSON用CPANモジュールをいっぱいダウンロードしていました(StrawberryPerlさいこうです)。

追伸:
英語の解説ページを発見。

日曜日, 5月 17, 2009

[Lift] より簡素に!

Liftの勉強をしてます。Webなフレームワークって便利ですね。
snippetで多用するbindについて、The Loopさんを参考に確認を。

まず、以下の書き方がサンプル的に分かりやすいモノ。

VIEW:
    <lift:helloDB.tstForm form="post">
    <testBox:lines>Lines</testBox:lines>
    <testBox:desc>To Do</testBox:desc>
    <testBox:submit>submit</testBox:submit>
    </lift:helloDB.tstForm>
SNIPPET:
    def tstForm(argForm: NodeSeq) = {
// とりあえずモデルオブジェクトを作成(!)
val hellom = HelloModel.create;

// 入力を受け取り保存するかを判断
def checkAndSave(): Unit = hellom.validate match {
// S.noticeでに値を出力
case Nil => hellom.save ; S.notice("Added "+hellom.desc)
case xs => S.error(xs) ; S.mapSnippet("helloDB.tstForm", doForm)
// S.redirectTo("/")は不要
// →何にせよ最後にdoFormしているから(再描画される)
}

// テンプレートへバインドする関数
def doForm(argForm: NodeSeq) = {
bind("testBox", argForm,
//"lines" -> toShow.toString,
"lines" -> toShow, // toShowでXMLを返すようにするから
"desc" -> hellom.desc.toForm,
"submit" -> submit("SAVE", checkAndSave)); // ボタンもタグ必要
}

// バインド実行(上の関数を)
doForm(argForm);
}

で、これをより簡単に書くと(HTML的な変更点はlabelで囲むこと)。

VIEW:
    <lift:helloDB.tstForm form="post">
    <testBox:lines>Lines</testBox:lines>
    <label for="desc">
        <testBox:desc>To Do</testBox:desc>
    </label>
    <testBox:submit>submit</testBox:submit>
    </lift:helloDB.tstForm>
SNIPPET:
    def tstForm(argForm: NodeSeq): NodeSeq = {
val hellom = HelloModel.create;

bind("testBox",argForm,
"lines" -> toShow, // toShowでXMLを返すようにするから
"desc" -> SHtml.text(hellom.desc, hellom.desc(_)), // descカラムへ書込み
"submit" -> SHtml.submit("SAVE", hellom.save)
)
}

なるほどー。かっこいい。

月曜日, 5月 04, 2009

[Scala] DynamicVariableとは

ScalaでDSLということで、DynamicVariableについて勉強中。あの記事においては、大体以下の流れであろうと思う。

DynamicVariableのインスタンスであるoutは、withValueメソッドの引数で与えられたインスタンスを示すようになる(そのインスタンスに成り代わってしまうイメージ)
・だから、outさんは共に与えられたパスでファイルを開いた_outさんになってしまう
・そして、その与えられたブロック内で呼ばれたwriteメソッドは、オーバライドされたout.value.writeであるので、結局_outさんが書く事になる

うーん。分かったような、分からんような。。withValueメソッドがset(そしてvalueがget)に相当していることは分かった。

なお、ここでwriteが書かれているような、メソッドに渡されるブロック(=クロージャ?/この表現も間違いな気がします)は、マニュアルではthunkとなっていた。

金曜日, 5月 01, 2009

[Lift] 作ってゆく流れは

基本的には以下流れ(yoroyoroさんライブコーディング資料から)。

0.コアとなるデータモデルを定義(MappedLongIndexとかをextendsする)
1.そのデータを記入するためのテンプレートを作成(webapp以下)
2.そのテンプレートで使うsnippetを作成(=入力フォーム)
3.それをBootにPath登録(メニュー化+ACL)
4.見るページのテンプレートを作る
5.そこで必要となるsnippetを作る
6.それをBootにPath登録

1,2,3と4,5,6みたいに、テンプレート作ってsnippet当ててBootに入れる。

追伸:
Liftはやっぱり大きめですね。
sweetというScalaで書かれたフレームワークもあるようで。。