2010年5月28日金曜日

柔軟なエンティティの拡張

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

これは実はmissingPropertyを利用して, typeの値に応じてそれぞれクラスContractedPerson, OfficialPersonのプロパティにアクセスできるようにしているだけなんですね.

typeの値によって, 動的にインスタンスごとに異なる役割を持たせることができるわけです.

もう一つはドメインクラスの定義を変えずに, ビュー (プロパティ・セット) を追加していくものです.

class Person { String name; static allowView = true }

としておくと

def george = new Person(name:"george")
george['contact'].tel = "0123-456-789"

これも前の例と同じようにmissingPropertyを利用して, クラスPersonContactにアクセスするようにしているだけです.

ビューであることを明示するために george['contact'] とかしていますが, もちろん普通にgeorge.contactと書いても同じです.

grailsのドメイン・クラスに対して, 単純にmixinしたり, categoryを追加しても駄目なんで, こんなことしていたわけですね...

2010年2月6日土曜日

Grailsのドメイン・クラスでnullな値はvalidateしてもnullable制約しかチェックされない. 同様にblankな文字列はblank制約しかチェックされない. 空の値を対象とする制約なんてあり得ないよね, と思えば, まぁ妥当性もないわけではないが...

「こういう場合にはnullを許す」みたいなカスタム制約を書きたいときには, 別の手を考えなくちゃいけないことになる. 面倒くさい.

2010年1月7日木曜日

もう使っている人も多いと思いますが, bashでgrailsコマンドの補完をしてくれるスクリプト. MacOSX用と書いていますが, 特にMacOSXには依存していないんじゃないかな.


grailsプロジェクト内 (create-domain-class, ..) と外 (create-app, ...) では補完されるコマンドが違っていたり, なかなかよくできてると思います.

同じ人が作った (補完スクリプトのオリジナル作者は別の人ですけど) もう一つ, これは面白い!


# 珍しくreblogしてしまいました

2009年12月27日日曜日

数値のinList

grailsで, 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のレベルでの制約評価の対象とはならない.

2009年12月15日火曜日

STS+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をreplaceにしておかないと, コマンド・ラインからもコメントを入れられなかったけど, 本当のところはどうなのか, 分かっていない.

2009年12月4日金曜日

spockを使う

さて, 普通にテストを書いていてもつまらないので:-) ちょっと違うことをやってみよう.

というか, JUnit系を普通に使っているだけだと, 昔ながらの「テスト要件に従った闇雲なテスト」をちょっと前倒しでやっているだけの話になりがちで, テスト書いている人は退屈だし, バグは早めに取れるけど, それだけの話しで, エキストリームじゃない.

もともとKent Beckが言っていたTDDは, 実は「テストの前倒し」とはだいぶ違って, そもそもテストですらなくて (結果的にテストっぽくなってるけど), 設計ingなわけだ. でも「アジャイルやってる」と主張する大方のプロジェクトで, そういうふうにテストを使っているところはあまり見ない. そもそもGrailsのようなDSLによる宣言的記述を中心にした環境を使っていると, そういう出番は限られる.

テストのもうひとつの視点は仕様としてのテストで, これは振る舞い駆動開発, BDDなどと呼ばれている. 今の仕事で, だらだらとした日本語の仕様書を書くのもあほらしいので, 仕様としてのテストを書いている. 動く仕様だ (ただしインスタンス・レベルで). 使うのは Spock. GroovyのBDD環境は, 他に easyB があるけど, いまいちである. テストが読めない. それは仕様書としてはだめだよね. Spockはなかなかいい.

GrailsでSpockを使うにはまず

$ grails install-plugin spock

すればいい.

http://grails.org/plugin/spock には "0.3-SNAPSHOT" とバージョンを明示してプラグインをインストールしろ, と書いてあるけど, 現時点ではバージョンを指定しなければ0.3がインストールされて, それでOK.

とりあえず最低限のドキュメントを訳した (というか, 現状はほぼこれくらいしかない).

これで, 「仕様を書く」ということと「品証としてのテスト」との違いが, プロジェクト・メンバにも分かりやすくなるんじゃないかな.

2010.01.05 追記

Grails 1.2には, 0.4-SNAPSHOTでないと動かない. grails install-plugin spockすれば, 0.4-SNAPSHOTがインストールされるみたい. ただし最初にgrails compileしないとtest-appできないので注意 (grails cleanしたときなども同様).

2009年8月11日火曜日

Autobase

Autobase pluginLiquiBaseのGrails wrapperで, LiquiBaseはRuby on RailsのMigrationぽいDBリファクタリング・ツールなんだけど, Autobaseが動かないんだな.


プロジェクトではこれはあるといいと思って評価したいんだけど, うちだけではなく, (作者の環境以外は:-) どこでも動かないらしい. 作者は忙しくて手を付けられないみたい.


かといって, XMLの塊であるLiquibaseを直接使うつもりはない (きっぱり). XMLを扱うつもりでよければ, Grailsで直接使うためのプラグイン (LiquiBase Database Refactoring for Grails) もあるけど.


# scriptsからは, srcもgrails-app/utilsも見えないのだよな... ところがたまに見えることがある...