tag:blogger.com,1999:blog-6983992918564932102024-02-19T13:13:53.931+09:00Grails goes ong線路は続くよ, どこまでも山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comBlogger73125tag:blogger.com,1999:blog-698399291856493210.post-67972157757631561802011-02-11T00:18:00.003+09:002011-02-11T09:20:49.240+09:00The Book of Geb - IntroductionGebのマニュアルをまず, イントロダクションだけ日本語に変換してみたよ.markdownをhtmlでレンダリングするのに, posterousを使ってみたけど, いまいちちゃんとレンダリングできていないところもある...GebはG*ファミリの特長, つまり漸進的改良主義をよく体現している. G*のやりたいことは技術的にはパラダイム・シフトじゃない. 今ある, もっともいい技術を集めて, もっとも使いやすい形にすること. あるいはそのためのプラットホームの提供 (その蓄積によっては, プロセス的なパラダイム・シフトにはつながるかも知れない).この程度のものを「新しすぎる」とか言って, 敬遠しているようでは先は暗い.かといって, 何も一足飛びに (流行っているらしいからと言って) Scalaやら何やらに現場が飛びつく必要もないし. ものを作るときのバランスの良さ, センスの良さが問われて山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-10767792980256660462010-11-29T09:51:00.003+09:002010-11-29T11:13:38.122+09:00MongoDB その2さて, redis のときと同じドメイン・クラスのインスタンスを, 同じように1万個作って, MongoDBに入れます.一個ずつ flush:true すると34秒くらい, まとめて flush:true すると3秒くらい. こちらはまぁ, 許容範囲, というか Grails らしい遅さだ:-)redis の場合に較べれば, とりあえずまともに動いているっぽい.ただし, flush:true する前に永続化された (と思っている) インスタンスにアクセスしても (例えばfind) 答えは返ってきません...とは言え, MongoDBだったら, 別に Grails のドメイン・クラスと inconsequential を経由するほどのことではない, という気もしないでもなかったりして(^_-)山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-4144899811543008822010-11-28T23:58:00.004+09:002010-11-29T10:39:01.870+09:00MongoDB その1どうも GORM for Redis の実装がうまくない, Spring 内の inconsequential がダメのような気がする, SpringSource から無用のプレッシャがあるんじゃないか...と言うところで, 今度は GORM for MongoDB を試してみることにします.まずは GORM for MongoDB のドキュメントを訳しましたよ.GORM for MongoDB ドキュメント和訳なるほど, なるほど...山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-29504976843692251642010-11-20T13:30:00.007+09:002010-11-29T10:25:33.517+09:00redis その4GORM for Redis を使ってみたところ, 頭を傾げざるを得ない結果になってしまいました (redis その2).そこで今度は Grails プラグインを経由せずに Groovy から直接 redis にアクセスしてみます.とは言っても, redis のプロトコルをそのまま使うのは辛いので, GORM for Redis でも使われている Jedis (http://github.com/xetorthio/jedis) という Java クライアント API から使います.ちなみに Jedis に Groovy 用に (とーっても) 薄い皮を被せた Gedis (http://github.com/xetorthio/gedis) と言うものもあるのですが, これは Jedis の最新 (1.4.x) でない版 (1.3.x) を要求するので止めておきます.GORM for 山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-10121656372185781062010-09-18T09:37:00.009+09:002010-11-29T10:38:36.498+09:00redis その3一目で分かるRedis一目で分かる Grails から Redis へのマッピングただし, 実際には今のところキーに非欧米文字は使えないようで, 適当なエスケープ/エンコードが必要です山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-1919436991763764422010-09-12T18:16:00.003+09:002010-09-13T12:49:29.965+09:00redis その2さて, 淡々といきますよ.redis本体をダウンロード, $make; $make test します.Grailsプロジェクトを作り, GORM for redisプラグインをインストールします.maven経由でいろいろなjarが付いてきます.grails-datastore-gorm-redis-1.0.0.M1.jargrails-datastore-gorm-1.0.0.M1.jarspring-datastore-web-1.0.0.M1.jar spring-datastore-core-1.0.0.M1.jar spring-datastore-redis-1.0.0.M1.jarjedis-1.0.0-RC4.jar最後のjedisは, Javaのredisクライアントですが, その他はバージョン番号から見て, このGORM for redisの一味 (山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-18940748367739766252010-09-11T23:18:00.006+09:002010-09-12T00:01:30.813+09:00redis その1ここ十数年, あらゆるデータ・ストレージがSQLに偏っていくのを苦々しく見ていた山田です.80年代前半はSQLもまだ成熟していませんでしたが, リレーショナルなデータベースの理論には面白いところもありました. BSD版UNIXには, UCBで作られたIngresが付いてきましたよね. Ingresはその後, いろいろあってPostgreSQLへとつながっていくわけですが, 当時はRDBMSを本番のデータ・ストレージに使うなんてとんでもない! という (今とはまったく逆の) 雰囲気でした.問題はリレーショナルなモデルそのものというよりは, SQLとか, 「データ中心モデリング」などという考え方にあるというのは, 後々に分かってくることです.当時メイン・フレームやミニコンはともかく, Unixなどで何をデータ・ストレージに使っていたかというと, ファイル・システム (それ以前のファイル・山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-4819239752183711352010-05-28T13:51:00.003+09:002010-05-28T14:20:18.002+09:00柔軟なエンティティの拡張uehajさんの最近の一連の "DCIらぶ" な投稿を読んでいて, 大昔, Grailsでこんなプラグインを書いて遊んでいたのを思い出しました.一つは動的に役割を与えるものです.例えばclass Person { String name; String type }というクラスがあったとします.def john = new Person(name:"john", type:"contracted")とすると, john は契約社員なので契約期間など契約社員特有のプロパティにアクセスできます.john.fromDate = new Date("2010/6/1")一方def paul = new Person(name:"paul", type:"official")とすると, paulは正社員なので給料など正社員特有のプロパティにアクセスできます.paul.salary = 1200これ山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-22475097636051759772010-02-06T22:18:00.002+09:002010-02-06T22:23:43.897+09:00Grailsのドメイン・クラスでnullな値はvalidateしてもnullable制約しかチェックされない. 同様にblankな文字列はblank制約しかチェックされない. 空の値を対象とする制約なんてあり得ないよね, と思えば, まぁ妥当性もないわけではないが...「こういう場合にはnullを許す」みたいなカスタム制約を書きたいときには, 別の手を考えなくちゃいけないことになる. 面倒くさい.山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-6838542441947406592010-01-07T12:53:00.002+09:002010-01-07T12:58:27.926+09:00もう使っている人も多いと思いますが, bashでgrailsコマンドの補完をしてくれるスクリプト. MacOSX用と書いていますが, 特にMacOSXには依存していないんじゃないかな.http://blog.jetztgrad.net/2010/01/updated-bash-completion-script-for-osx-and-grails-1-1-1-2/grailsプロジェクト内 (create-domain-class, ..) と外 (create-app, ...) では補完されるコマンドが違っていたり, なかなかよくできてると思います.同じ人が作った (補完スクリプトのオリジナル作者は別の人ですけど) もう一つ, これは面白い!http://blog.jetztgrad.net/2010/01/released-grails-spy-plugin/# 珍しく山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-11722353147372435822009-12-27T16:03:00.002+09:002009-12-27T16:10:54.747+09:00数値のinListgrailsで, constraintsに"inList:['foo', 'bar', 'baz']などと書いておけば, scaffold画面ではselectorが使われるが, 文字列ではなく数値だとNull Pointer Exceptionになる. このときは次のようにしておけばよい.$ grails install-templatesで, /src/templates/scaffolding/renderEditor.templateのrenderNumberEditor()メソッドの"if (cp.inList) { ... }" の...部分をrenderStringEditor()の同じ部分と入れ替える.1.3では直すといっているけどね.ちなみに画面ではうまくいくが, GORMのレベルでの制約評価の対象とはならない.山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-4553191475224239232009-12-15T15:33:00.003+09:002009-12-15T16:28:02.316+09:00STS+Snow Leopard現時点では STS がいちばんまともなGrails IDEなわけだが, Snow Leopardにすると Java1.6がデフォルトで, これはfile.encodingがSJISなのである (Java1.5は多分utf-8だった).普通のエディタとかはeclipseの環境設定すれば良いだけだが, バージョン管理のコメントとかはSJISになってしまって, 例えばhgに断られる (HGENCODINGMODEをreplaceとかignoreにすれば断られはしないけど, 当然化ける).仕方がないので, STS.app/Contents/MacOS/STS.ini に-Dfile.encoding=utf-8 という一行を足す.あまり麗しくないけどしようがない. IntelliJ IDEAとかでも同じじゃないかな, どうかな.それとは別にmercurialの方でもHGENCODINGMODEを山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-69701220007914961772009-12-04T15:43:00.009+09:002010-01-05T17:14:08.149+09:00spockを使うさて, 普通にテストを書いていてもつまらないので:-) ちょっと違うことをやってみよう.というか, JUnit系を普通に使っているだけだと, 昔ながらの「テスト要件に従った闇雲なテスト」をちょっと前倒しでやっているだけの話になりがちで, テスト書いている人は退屈だし, バグは早めに取れるけど, それだけの話しで, エキストリームじゃない.もともとKent Beckが言っていたTDDは, 実は「テストの前倒し」とはだいぶ違って, そもそもテストですらなくて (結果的にテストっぽくなってるけど), 設計ingなわけだ. でも「アジャイルやってる」と主張する大方のプロジェクトで, そういうふうにテストを使っているところはあまり見ない. そもそもGrailsのようなDSLによる宣言的記述を中心にした環境を使っていると, そういう出番は限られる.テストのもうひとつの視点は仕様としてのテストで, 山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-32378533402742372052009-08-11T15:59:00.001+09:002009-08-11T15:59:46.875+09:00AutobaseAutobase pluginはLiquiBaseのGrails wrapperで, LiquiBaseはRuby on RailsのMigrationぽいDBリファクタリング・ツールなんだけど, Autobaseが動かないんだな.プロジェクトではこれはあるといいと思って評価したいんだけど, うちだけではなく, (作者の環境以外は:-) どこでも動かないらしい. 作者は忙しくて手を付けられないみたい.かといって, XMLの塊であるLiquibaseを直接使うつもりはない (きっぱり). XMLを扱うつもりでよければ, Grailsで直接使うためのプラグイン (LiquiBase Database Refactoring for Grails) もあるけど.# scriptsからは, srcもgrails-app/utilsも見えないのだよな... ところがたまに見えることがある...山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-49930554675241579332009-08-10T12:35:00.001+09:002009-08-10T15:53:05.130+09:00Hudsonを動かしてみたよhttps://hudson.dev.java.net/ に行って, 最新版をダウンロードする. MacOSXならば, ダウンロードした hudson.war をダブル・クリックするだけ. http://localhost:8080/ をブラウズすると, すでにHudsonは立ち上がっている.「Hudsonの管理」メニューから「プラグインの管理」に行って, 例えばGrails, Groovy, Mercurialの各プラグインをインストールしてみる.「Hudsonの管理」メニューから「システムの設定」に行って, Grails Builderに「追加」して, 適当な名前 (grails-1.1.1) と GRAILS_HOME 環境変数と同じ値を設定する. で, 保存. 「Hudsonの管理」メニューから「設定の再読み込み」をした方がいいみたい.ダッシュボードに戻り, 適当に名前を付けて山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-13142855823402213502009-08-05T10:52:00.001+09:002009-08-09T16:43:21.285+09:00Grailsのテスト・ツールGrailsのようにアプリケーションを作るのが, 簡単, というか仕様を書けばいいだけ, になってくると, 相対的にテストの比重がどんどん大きくなってくる. となると考えるのが, テストをどうやって楽にするか, だ.Grailsのテスト・ツール, 特にテスト・データ管理のプラグインを簡単にまとめておく.DBUnit PluginJavaのデータベース用テスト・ツール, DBUnit をそのままプラグイン化したもの.http://code.google.com/p/dbunit-plugin/ (コード)http://grails.org/plugin/dbunit基本的には, DBUnitそのものだから, XMLでデータセットを <PROJECT>/test/datasets に定義して<?xml version="1.0" encoding="UTF-8"?>&山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-55284088291619349142009-07-05T17:55:00.001+09:002009-08-05T10:54:42.741+09:00criteriaでのプロパティ指定Grailsのユーザ・ガイドのCriteriaの項を読んでいて, こんな例が出ているので,def criteria = Task.createCriteria()def tasks = criteria.list{eq "assignee.id", task.assignee.idjoin 'assignee'join 'project'order 'priority', 'asc'}「ふーん, プロパティ名には'.'を含むナビゲーションが書けるのね」と軽く読み飛ばしていたのだが, それは一般には無理で, 'id'の場合のみ許されるようなのだ, と言うことが分かってきた.じゃあ, それ以外の「行った先の」プロパティでクライテリアを組み立てたい場合にはどうすればいいか.eq "assignee", Person.findByName("foo")なんてのが一つ. でもこれはid的でない山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-68665392374434460582009-07-01T15:11:00.000+09:002009-07-01T15:22:54.419+09:00simple groovy code reading - MOPMOP, Meta-object Protocolとは, プログラム自身をプログラミングの対象として扱う時のAPIです. もっとおおざっぱに言うと, Javaのリフレクションをもっと使いやすく, 柔軟に, 強力に, 綺麗にしたようなものだと思えばいいでしょう. ある意味ではいわゆるアスペクト指向プログラミングもここに含まれます (それをもっと汎用的にしたものです).GroovyのMOPはいちばん基底では, インタフェイスgroovy.lang.MetaObjectProtocolで規定されています. MetaClass extends MetaObjectProtocol MutableMetaClass extends MetaClass MetaClassImpl implements MutableMetaClass ExpandoMetaClass extends 山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-30985211175777307082009-07-01T14:21:00.001+09:002009-07-01T14:24:54.971+09:00simple groovy code reading - closureGroovy最大の特徴のひとつであるクロージャは, 謎でも何でもなく単なるClosureクラスのインスタンスです. なので, クロージャが何かはgroovy.lang.Closureを見てみるのがいちばんです.Closureでいちばん目立つのは, call()とcurry()です. call()は名前のまま, そのクロージャに引数を与えて実行します. 単にmetaClassのinvokeMethodを呼んでいるだけですね.curry()は引数の一部を固定したクロージャを作るものですが, その通り, 引数の一部を値として持つサブクラスCurriedClosureを作って返しているだけです. 実際に呼び出すときには, この固定した値をもとのClosureの引数として与えなければならないのですが, それはinvokeMethodを実装したMetaClassImplの中で行われています.その他に山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-49620640298531504022009-07-01T12:12:00.000+09:002009-07-01T12:13:00.771+09:00simple groovy code reading - operatorsGroovyには, Javaに較べて多くの演算子があります. またJavaでは単なる構文要素であるものが, 演算子として再定義できたりします. それらはとても便利なのですが, どんな演算子が使えるか 使えたとして優先順位はどうなのか 多重定義する時のメソッド名はなど, なかなかまとまって調べられる場所もないのです...そういうときには org.codehaus.groovy.syntax.Types を見てみましょう (えーと, あまり本気にしない方がいいかも知れませんよ:-) 特によい子は真似しないように).ここには演算子のシンボル定義や優先度が書かれています.だからてっきり, is()に相当する "===" (昔はあった) が使えるものかと思ってやってみると...groovy:000> 1 === 1ERROR 山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-61025366368242000482009-07-01T11:48:00.001+09:002009-07-02T19:23:56.995+09:00simple groovy code reading - nullGroovyでの null (ナル) オブジェクトは, org.codehaus.groovy.runtime.NullObjectの (唯一の) インスタンスです.で, NullObjectの中身を見てみると, Object invokeMethod(String name, Object args) の中で,throw new NullPointerException("Cannot invoke method " + name + "() on null object");しています.これこそ我々がしょっちゅう見る, あの「文字列」の本体なのですね.でもさ, nullにメッセージを送ったらこんな文字列が返ってくるなんて不合理だと思いませんか? オブジェクト指向以前の「関数呼び出し」の臭いが芬々と漂っているようです.nullに何かを依頼したら, 無視して欲しい (つまり単にnullを山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-42915822232332325452009-07-01T11:11:00.001+09:002009-07-01T12:51:35.191+09:00simple groovy code reading - Object methodsJavaでは, Objectに定義されているメソッドは, ごく少数で基本的なものに限られています. clone eqauls finalize getClass hashCode notify, notifyAll toString waitそれに対して, Groovyでは, お馴染みprintln始め, 非常に多くのメソッドを使うことができます.Javaでは次のように, きわめてトップダウンかつアドホックな思考パタンになっているわけです.「printlnの責務を持つのは当然出力を担当するやつ (PrintStream) だよな. printlnしたければPrintStreamを出力先を指定してnewして, それにprintlnすればよかろう」「ま, しかしprintlnなんてコードのどこからでもしたいだろうし, 出力先はほとんどは標準出力だろうから, ちょっとだけ便利山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-1223238286563851142009-07-01T10:02:00.001+09:002009-07-01T10:02:56.274+09:00simple groovy code reading - importJavaではjava.langだけはimportしなくても使えることになっています (デフォルト・パッケージ) が, それ以外はいっぱいimportしなければなりません. 特定の機能を実現するパッケージをimportで指定するのはいいとして, java.utilのような基本的な機能までいちいちimportしなければならないのは, 納得がいきませんよね.Groovyでは java.util.* java.io.* java.net.* groovy.lang.* groovy.util.* BigInteger BigDecimalがデフォルトでimportされます. これはもちろんスクリプト言語として, 普通に使うものはimportせずに済むようになっているわけです.では, simple groovy code readingの一発目として, どこでこれらがimportされ山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-77769544627760672722009-06-23T14:35:00.001+09:002009-06-23T14:35:40.356+09:00WebFlowTestCaseが変わったらしいどうやらgrails-1.1からWebFlowTestCaseが変わったらしい. なので「Grails徹底入門」のWebFlowのテストはもう古い.でも grails.orgの記述もアップデートされてない! 1.1.1のオンラインのuser guideのみ, こそこそ消してあるぜ:-)新しいWebFlowTestCaseは次のようになっています.startFlow()対象flowの最初の状態をトリガする. 前はこれでViewSelectionが戻っていたけど, 今はvoid.signalEvent(String)対象flowにイベントを送る. startFlowと同様, 今やViewSelectionは返されない (ExternalContextを返す).getFlowDefinition()対象flowの定義を得る.setCurrentState(String)新しいflowを開始し,山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.comtag:blogger.com,1999:blog-698399291856493210.post-29489266040891189022008-12-03T13:21:00.001+09:002008-12-03T13:21:36.686+09:00Groovy Magazine 2008 年 12 月号 (通巻 2 号)今号は 36 ページ $5. ご注文はこちらから.素の PDF にコード例が付いてきます. Grails で iUI という AJAX ライブラリを使って, iPhone 用 Web アプリを作る (Grails プロジェクト付き) Groovy でリッチな Swing アプリを作る パートII GORM の解説記事 contentsieve.com, addsieve.com というサイトを運営しているMetaSieveの人へのインタビュ Plugin Corner の話題は Grails Testing Plugin コミュニティ・ニューズ山田正樹http://www.blogger.com/profile/11640381508311247017noreply@blogger.com