2005-06-01(Wed) [長年日記] [Edit]
■1 「Kent BeckとJUnit4の作業中」
Actually, the JUnit journey isn't over yet and Kent and I are currently working on JUnit 4. We are continuing to evolve JUnit in a test-driven way. One of our themes is to lower the barriers to entry. To do so we are leveraging J2SE 5 features like annotations to make JUnit easier to use.
TestNGみたいな感じになるのかな。NUnitもそんな感じでやれるんだっけ。例外を期待するテストとかはannotationで書けたほうが良いと思う。楽しみ。
追記
JUnitプロジェクトでVersion4ブランチが切られていて、t-wadaさんがすでに動かしていた。例外期待やsetUp/tearDown、クラス単位でのセットアップとかはannotationで書けるようになってる。
■2 Quick JUnit プラグイン 0.1.10.1.1.1 リリース
id:koichikさんからいただいたパッチを取り込みました。ありがとうございます。
ChangeLog
- ネストクラス、匿名クラス上にエディタのカーソルがポイントされている状態でのテスト実行に対応しました。
Happy, testing!
追記
ソフトウェア更新サイトのパッケージングをミスりました。0.1.1.1が最新版です……すみません。そして、id:koichikさん、報告ありがとうございます。sf.jpのアーカイブは問題ないので、0.1.1が最新です。
2005-06-02(Thu) [長年日記] [Edit]
■1 車輪の再実装: 簡易DIコンテナ on Groovy
Groovyで、クラスの数が10〜15程度の規模で書かれたコードをDRY原則に従ってリファクタしていると、EoT(Ease of Testing:テスト容易性)の観点からDIコンテナが欲しくなってきた。
しかし、この規模のコードではSeasar2はおろか、PicoContainerですらヘビーウェイト。なので、id:t-wadaさんとTDD && ペアプロで作成してみた。
機能としてはAOPもXMLによる設定も無く、オブジェクトのwiringだけだが、我われの現在の用途には必要十分。インジェクション方法は、ブロック・インジェクション——Groovyだからクロージャ・インジェクションと呼ぶべきか——のみをサポート。車輪の再実装は善。って、『Linux mgazine』(2005.02)のMatzダイコンを丸パクリなので、再実装ですらないか。
利用イメージ
こんな感じ:
class Blog {
input
display
...
}
class Input {...}
...
dicon = new DICon()
dicon.regist("blog") {|c| new Blog(input:c.input(), display:c.display)}
dicon.regist("input") {|c| new Input()}
dicon.regist("display") {|c| new Display()}
blog = dicon.blog # dicon.blog() でも良い
blog.display...
テストコード
ガリガリ書き流したので安直だったりコピペだったりで手抜き。「Code as Documentation」になってない。
1 package com.kakutani.groovy.di
2
3 class DIConTest extends GroovyTestCase {
4 dicon
5
6 void setUp() {
7 dicon = new DICon()
8 }
9
10 void testOneCompoent() {
11 dicon.regist("myString") { "Hello World" }
12 assertEquals("Hello World", dicon.myString)
13 }
14
15 void testTwoCompoent() {
16 dicon.regist("myString") { "Hello World" }
17 dicon.regist("foo") { "Hello Foo" }
18 assertEquals("Hello Foo", dicon.foo)
19 }
20
21 void testDependency() {
22 dicon.regist("lineItem") { "ThinkPad"}
23 dicon.regist("order") {|c|
24 order = []
25 order[0] = c.instance("lineItem")
26 order
27 }
28
29 assertEquals("ThinkPad", dicon.instance("order")[0])
30 }
31
32 void testPropertyMissing() {
33 dicon.regist("lineItem") { "ThinkPad" }
34 dicon.regist("order") {|c|
35 order = []
36 order[0] = c.lineItem
37 order
38 }
39
40 assertEquals("ThinkPad", dicon.order[0])
41 }
42
43 void testMethodMissing() {
44 dicon.regist("lineItem") { "ThinkPad" }
45 dicon.regist("order") {|c|
46 order = []
47 order[0] = c.lineItem()
48 order
49 }
50
51 assertEquals("ThinkPad", dicon.order()[0])
52 }
53 }
プロダクトコード
Classic Syntax。JSR Syntaxは気にくわない、というのもあるけれど、MarkupとBuilderが使えないと困るので、beta10を採用。
行数は39行。所要時間は、mixiの日記のタイムスタンプから算出すると29分。getPropertyとinvokeMethodのオーバーライドでハマった(自分で翻訳していたというのに)。メソッドの仮引数の型を明示しないとオーバーライドできないのね……。
ちなみに、ブロック・インジェクションなMatzダイコンはRubyで20行。
1 package com.kakutani.groovy.di
2
3 class DICon {
4 instances
5 services
6
7 DICon() {
8 instances = [:]
9 services = [:]
10 }
11
12 DICon regist(name, closure) {
13 services[name] = closure
14 this
15 }
16
17 Object instance(name) {
18 if (instances[name] != null) return instances[name]
19 closure = services[name]
20 component = closure.call(this)
21 instances[name] = component
22 }
23
24 getProperty(String name) {
25 try {
26 return metaClass.getProperty(this, name)
27 } catch(MissingPropertyException e) {
28 return instance(name)
29 }
30 }
31
32 invokeMethod(String name, Object args) {
33 try {
34 return metaClass.invokeMethod(this, name, args)
35 } catch(MissingMethodException e) {
36 return instance(name)
37 }
38 }
39 }
さらに先に進むために
GroovyでAOPというかインターセプターというか、そーゆうのを仕込もうと思ったらどういうやり方があるのかなあ……。AspectGとか無いのかな。
■2 TodoListTutorial with Rails
id:babieさんによる翻訳。お疲れさまでしたッ!
2005-06-03(Fri) [長年日記] [Edit]
『アジャイルプロジェクトマネジメント』
■1 まだ書誌情報も少なく、書影もないけれど、amazonで予約できるようになった模様。ジム・ハイスミスの最新刊の邦訳。2005/06/09発売予定?
2005/06/04 追記: 買ってきた
たぶんいわゆる"フラゲ"ってやつだ。書籍の最後の最後にAdvanced Power ManagementじゃないほうのAPMの価値・原則・プロセスフレームワーク・プラクティスのをまとめた表がついている。『コンスタンティン』と同じように、最後までお見逃しなく。
訳者あとがきにクレジットがある。恐縮だ。
ちょっと読んでみた
『適応型ソフトウエア開発』のときもそうだったのだが、私にとってはハイスミスの本は殺し文句満載で、線を引きながら読むとほぼ全ページ線だらけになってしまう。なので、初読では線が引けない。
ちなみに、KKDさんの『ASD』は、黄色い付箋紙が山のように挟んであって御堂筋の銀杏並木のような状態になっていた。その気持ち、よくわかる。
でも
『アジャイルソフトウェア開発エコシステム』は、KentBとファウラーのインタビューを読んだ以外は、通読できていない。
2005-06-14(Tue) [長年日記] [Edit]
■1
PofEAA読書会:第4回参加者募集のお報せ
4回目をやります。Wikiの記述が最新の一次情報です。以下、抜粋。
開催概要
- 日時:2005/6/26(日) 13:00〜18:00頃
- 場所:(株)オージス総研 東京オフィス会議室
内容(予定)
(第4章は飛ばします)
- ポジションペーパー(立場表明書)ベースの自己紹介
- Chapter5: Concurrency(第5章 並行性)
- 関連して、もうちょっとネタがあるかも……
終了後、懇親会があると思います(参加はもちろん任意です)。
参加申込方法
[email protected] 宛に「PofEAA読書会第4回参加希望」みたいな感じのメールを送ってください。 本文には、参加者の名前ぐらいは書いていただけると助かります。
申込締切
- 2005/06/22(水) 17:00
申込注意事項
- メーリングリストに参加されている方も、読書会への参加にあたっては、改めて参加申込を行ってください。
- たぶん大丈夫だと思いますが、申込多数の場合は、何らかの手段が講じられる可能性があります。
2005-06-16(Thu) [長年日記] [Edit]
■1 反応すべきネタ、反応したほうがよさそうなネタ
というのが幾つかあるの。が、今はちょっと手が回らない状態。しばらくお待ちください……。心当りのあるみなさん、ごめんなさい。
2005-06-17(Fri) [長年日記] [Edit]
■1 「Reflectionを利用して再帰的にオブジェクトの内容を文字列化する」@CodeZine
arton特派員の記事。クレジットされてる。わーい。私は大したこと何もしてないけど。おっ。推奨環境がNetBeansだ。
CodeZineでのartonさんによる他の記事としては、いかにも"artonっぽい"(と私は感じた)「JavaとSAXパーサでXMLベースのプログラミング言語を作る」もあり。
2005-06-20(Mon) [長年日記] [Edit]
■1
PofEAA読書会:第4回参加受付、あと2日
4回目の申込締切は6/22(水)です。まだ申込枠には空きがあります。Wikiの記述が最新の一次情報です。以下、抜粋。
開催概要
- 日時:2005/6/26(日) 13:00〜18:00頃
- 場所:(株)オージス総研 東京オフィス会議室
内容(予定)
(第4章は飛ばします)
- ポジションペーパー(立場表明書)ベースの自己紹介
- Chapter5: Concurrency(第5章 並行性)
- 『.NETエンタープライズWebアプリケーション開発技術大全 Vol.5 トランザクション 設計編』第3部 複雑なトランザクション制御、のサマリ
終了後、懇親会があると思います(参加はもちろん任意です)。
参加申込方法
[email protected] 宛に「PofEAA読書会第4回参加希望」みたいな感じのメールを送ってください。 本文には、参加者の名前ぐらいは書いていただけると助かります。
申込締切
- 2005/06/22(水) 17:00
申込注意事項
- メーリングリストに参加されている方も、読書会への参加にあたっては、改めて参加申込を行ってください。
- たぶん大丈夫だと思いますが、申込多数の場合は、何らかの手段が講じられる可能性があります。
2005-06-21(Tue) [長年日記] [Edit]
■1 QuickJUnitプラグイン: 3.1対応、救援求ム
quick-junit-develは35人しかsubscribeしてないので(!)、こっちにも書いておこう……。
Eclipse3.1系プラグインを触っている方の助けを求めています。
Eclipse 3.1M7で、「PDE enforces code accessibility」というのが導入されたそうで、おかげでinternal系のクラスが軒並、参照できなくなってる模様。
プリファレンス系のAPIも大きく変わっちゃってる……。振り切られました。あうあう。
私が3.1系のプラグインのつくり方を勉強して直していると、3.1リリース時点での対応は間に合わないこと確実。なので、3.1系のプラグインのことがわかる方、アドバイスをいただけないでしょうか。メーリングリストでお待ちしております。
■2 車輪の再実装: 簡易DIコンテナ on Groovy with AOP
前回、39行でDI機能を実装したGroovyのダイコン。今度はTraceInterceptorが必要になったので、実装してみた。AOP(というかInterceptor)の実装のことはよくわからないのだけれど、TDDでやったら動いちゃった。TDDすごいなあ。コンテナ部分のコードは45行増えて、84行になった。
利用イメージ
たとえば、こんなクラスをDIしてTraceInterceptしたいとする。
class TraceStub {
doSomethingWith(arg1, arg2) {
"doneSomething"
}
void throwException() {
throw new RuntimeException("expected")
}
}
コンテナに登録するときはBlockInjectionだよね、フツウ。
dicon = new DIContainer()
dicon.regist("myComp") { new TraceStub() }
登録したmyCompにinterceptorを適用したいときは:
dicon.intercept("myComp").with { TraceInterceptor.class }
こうでなくっちゃ。で、
dicon.myComp.doSomethingWith("someArg", "otherArg")
って呼んだら:
BEGIN com.kakutani.gradicula.TraceStub#doSomethingWith('someArg', 'otherArg')
END com.kakutani.gradicula.TraceStub#doSomethingWith('someArg', 'otherArg') : doneSomething
と出て欲しいし、
dicon.myComp.throwException()
って呼んだら:
BEGIN com.kakutani.gradicula.TraceStub#throwException() END com.kakutani.gradicula.TraceStub#throwException() Throwable: java.lang.RuntimeException: expected
と出て欲しい。
DIContainer.groovy
45行も増えてしまった。なんでこんな設計になっているのか自分でもよくわかってない。テストを通るように実装したらこうなっちゃった。たぶんいろいろマズいと思うけど、自分たちが使うには充分だ。
1 package com.kakutani.gradicula
2
3 class MethodInvocation {
4 target
5 methodName
6 args
7
8 proceed() {
9 target.invokeMethod(methodName, args)
10 }
11 }
12
13 class InterceptProxy {
14 target
15 proc
16
17 InterceptProxy with(closure) {
18 proc = closure
19 this
20 }
21
22 invokeMethod(String name, Object args) {
23 try {
24 return metaClass.invokeMethod(this, name, args)
25 } catch(MissingMethodException e) {
26 interceptor = proc.call()
27 if (interceptor.class == Class.class) {
28 interceptor = interceptor.newInstance()
29 }
30 m = new MethodInvocation(
31 target:target,
32 methodName:name,
33 args:args)
34 return interceptor.invoke(m)
35 }
36 }
37 }
38
39 class DIContainer {
40 instances
41 services
42 interceptors
43
44 DIContainer() {
45 instances = [:]
46 services = [:]
47 interceptors = [:]
48 }
49
50 DIContainer regist(name, closure) {
51 services[name] = closure
52 this
53 }
54
55 InterceptProxy intercept(name) {
56 if (interceptors[name] != null) return interceptors[name]
57 proxy = new InterceptProxy(target:instance(name))
58 instances[name] = proxy
59 interceptors[name] = proxy
60 }
61
62 Object instance(name) {
63 if (instances[name] != null) return instances[name]
64 closure = services[name]
65 component = closure.call(this)
66 instances[name] = component
67 }
68
69 getProperty(String name) {
70 try {
71 return metaClass.getProperty(this, name)
72 } catch(MissingPropertyException e) {
73 return instance(name)
74 }
75 }
76
77 invokeMethod(String name, Object args) {
78 try {
79 return metaClass.invokeMethod(this, name, args)
80 } catch(MissingMethodException e) {
81 return instance(name)
82 }
83 }
84 }
TraceInterceptor.groovy
S2のTraceInterceptorの丸パクリにインスパイアされました。出力はロギングAPIじゃなくてprintlnで手抜き。
1 package com.kakutani.gradicula
2
3 class TraceInterceptor {
4 Object invoke(invocation) {
5 buf = renderSignature(invocation)
6 println("BEGIN " + buf)
7 try {
8 result = invocation.proceed()
9 buf << " : ${result}"
10 result
11 } catch (Throwable t) {
12 buf << " Throwable: ${t}"
13 throw t
14 } finally {
15 println("END " + buf)
16 }
17 }
18
19 private StringBuffer renderSignature(invocation) {
20 buf = new StringBuffer(100)
21 buf << "${invocation.target.class.name}#"
22 buf << "${invocation.methodName}(${renderArgs(invocation.args)})"
23 buf
24 }
25
26 private String renderArgs(args) {
27 buf = new StringBuffer()
28 buf << args.toList().inject("") {|str, a| "'${a}', " }
29 if (0 < buf.length()) buf.setLength(buf.length() - 2);
30 buf.toString()
31 }
32 }
さらに先に進むために
Interceptorの登録の仕方のバリエーションを増やす。特定のメソッドにだけinterceptするための指定とか。
2005-06-22(Wed) [長年日記] [Edit]
■2 車輪の再実装: Gradicula、軽量DIコンテナ with AOP for Groovy
たぶん興味持っるのはid:t-wadaさんとid:ma2さんぐらいだけだと思うけど。sf.jpでプロジェクト申請が通ったので、登録。
なぜかshellサーバにログインできなくなるわ(cvsはOK)、コミットメールの設定は間違えるわ、と散ざんな状況 だけど、コードのインポートとメーリングリストは用意済。「在庫」管理にはヌーラボさんのBacklogを使わせてもらうことにした。
2005-06-24(Fri) [長年日記] [Edit]
■1 「Rubyワールドは関わる人に金の匂いがしない。」
肉食系開発者のまさたかさんのコメントを部分的に引用:
- Rubyワールドは関わる人に金の匂いがしない。->これはいけない。みんな遊んでるんじゃないんだから。。。遊びで終わらせるならいいけどね。(攻略)
- 最後に私見。Railsを「輸入」してよろこんでるだけなのはいかがなものかと。ちょっと楽しくないよね。そんなこと無いのかな?言語仕様を握ってる人も近所にいるんだし、AOT&VMを今つくろうとしているんだから、Ruby Enterprise Editionとかやったらいいんじゃないかな。面白いと思うんだけどな。
引用終わり。これに対して「物申す!!」と言えるような見識も実力もないので、チラシの裏に書くべきような話。
いまのところRubyには「儲ける構図」が無い。金の匂いがしない。言語仕様とか処理系というよりは、エコシステム的な課題という印象も強い*1。エコシステム的な課題というのは、モダンIDEがあったりとか、分散トランザクションとか非同期メッセージングとか。Java界はエコシステムが充実している(JSRはちょっとアレだけど)。
エコシステム的な視点からは、Ruby界にとってRailsは「事件」なのだと思う。gemsを前面に出して来たりとか、Fowlerも『Language Workbenchs以下略』(この記事はヤヴァイ。kdさんがんがれ)でちょっとだけ言及しているような、メタプログラミング——DHH曰く、『オレはそれを「便利だね」と呼ぶね』のやりすぎな使い方とか。
唐突にまとめると、Rubyの威光がギョーカイを覆いつくす!!となることを望みはしないのだけれど(なったら面白そうだけど)、私ぐらいの人間でもRubyでおいしいご飯を食べられるぐらいになる日がくるといいなあ、と思うし、そうなるようにコツコツやっていこうと思います。
Python界にはPEAK(Python Enterprise Application Kit)というのがあるらしいよ、とKKDさんに教えてもらったけど、普及とか利用はどれぐらいされてるのかなあ。
エコシステム
エコシステムって便利でいい言葉で、重要だと思うんだけど、アジャイル界隈では見事にスベったね。
*1 勿論、言語仕様や処理系も無関係ではない。比重というか相対的な話。
2005-06-26(Sun) [長年日記] [Edit]
■1 PofEAA読書会: 第4回 体調不良で早退という失態
金曜の夜から熱発。ひたすら寝て回復を図るも果せず。液体・錠剤・ビタミン剤などなどでドーピングしてオープニングとポジションペーパーの司会までどうにかこなしたものの、終盤は妙な汗をかいていたり。後を唐突に隣に座ってたKKDさんに押しつけて(ありがとうございます)、早退。参加されたみなさん、すみませんでした。そして、ありがとうございました。いろいろ話をしたいことも多かっんだけどな……。
現場では、次回の日程(7/30(日))と担当者が決まっていたらしい。すばらしい。
2005-06-27(Mon) [長年日記] [Edit]
■1
息子:Quarterly Reflection (3)
9ヶ月経過。
- 移動手段を獲得。ハイハイが完成。掴まり立って、伝い歩く。
- 独り言のような謎の発声を繰り返す。相変らずよく笑う。
- 離乳食の進捗はビミョウ。うどんを食べた。うどん重要。
- ストローでお茶が飲めるようになった。時どき盛大にこぼすけど。
- 風邪をひいた。
- ボールを掴んで、投げようとする(落ちるだけなんだけど)。
- インタラクティビティの向上。「一緒に遊んでる」という手応えを感じる。
次のReflectionではもう一歳か。早いなあ。
2005-06-29(Wed) [長年日記] [Edit]
■1 「オブジェクト倶楽部 2005夏イベント: プロジェクト・ファシリテーション 〜 「ものづくり」から「チームづくり」へ 〜」
うろうろしてますので、参加される方は会場で見かけたら声をかけてやってください。こんかいはライトニングトークスの司会をやる予定。
リーン開発の現場 カンバンによる大規模プロジェクトの運営(Henrik Kniberg/角谷 信太郎/市谷 聡啓/藤原 大)
『なるほどUnixプロセス ― Rubyで学ぶUnixの基礎』
SCRUM BOOT CAMP THE BOOK(西村 直人/永瀬 美穂/吉羽 龍太郎)
実践テスト駆動開発 テストに導かれてオブジェクト指向ソフトウェアを育てる(Steve Freeman/Nat Pryce/和智 右桂/高木 正弘)
The RSpec Book (Professional Ruby Series)(David Chelimsky/Dave Astels/Zach Dennis/角谷 信太郎/豊田 祐司/株式会社クイープ)
アジャイルサムライ−達人開発者への道−(Jonathan Rasmusson/西村 直人/角谷 信太郎/近藤 修平/角掛 拓未)
アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~(Mike Cohn/マイク コーン/安井 力/角谷 信太郎)
インターフェイス指向設計 ―アジャイル手法によるオブジェクト指向設計の実践(Ken Pugh/角谷 信太郎(監訳)/児島 修)
アジャイルプラクティス 達人プログラマに学ぶ現場開発者の習慣(Venkat Subramaniam/Andy Hunt/木下 史彦/角谷 信太郎)
JavaからRubyへ ―マネージャのための実践移行ガイド(Bruce A. Tate/角谷 信太郎)










○ babie [角谷さんが「Kent BecktとJUnit4の作業中」かとオモタw]
○ nahi [Becktってvisual系ぽいかも]
○ かくたに [ガンヲタっぽくなってしまった……。]
○ 咳 [わはは > Beckt]