著作一覧 |
やっぱりDVDせめてCDの読み取り装置が付いていないと辛いかな。
(とは言え、ネットワークがあるから無くても済んではいるけれど)
キーボードは使えば使うほど打ちやすく感じてきた(底打ち感はやっぱりあるけど)。
思えば、最初にすごく気に入ったキーボードはPC98ノートのi386 12MHzが乗ったやつだった。あれはぺたぺただったけど、その分バネが強くて打ちやすかった。
そして、コンパックDeskpro33に付属のやつ。梨地加工があまりに気持ちよくて意味無くキーボードの上に指を置いて滑らせてみたり。フェチですな。でも、それくらい気持ちよかった。硬くて歯ごたえがあって一切打ち間違う余地がなくて、本当にすばらしかった。これがあまりにも気持ちよいので、CTRLが変な場所にあってもまったく気にならず、結局どこにCTRLがあっても気にならなくなった。実は今も手元にはあるのだが、なんか微妙に普通と違うようで今のマシンのPS2ポートに入れるとハングするのだが。
というわけで、一度本当に良いキーボードにめぐり合ったため、後は何を買っても(自宅)、あてがわれても(仕事)、良いという感覚は持てない。悪いか悪くないかの2種類だ。で、悪くないミネビアのキーボードを家では使っていたのだが(ずいぶんと落ちるのだが)、それが壊れてから何世代か。エレコムとか三和サプライとかどれも全然、だめだめだ。特に三和サプライのUSBのやつはコンパクトでストロークも悪くなく結構付き合えるかもと買ったのだが致命的に斜めに打った場合に引っかかりがあってすぐゴミと化してしまったり。で、あるとき秋葉原でコンパックのキーボードが投売りされていたので触ったら、もちろんDeskpro33のとは比べ物にはならないが、そんなに悪くはない。キーボード自身もずしりと重いし。で、腐りきってもコンパックとそれなりに喜んで買って帰って使い始めたらどうもどっかで打ったことがある感覚を覚える。でよくよく見たらミネビア製で、回りまわって元に戻ったかと感慨ひとしお、とともに、あのDeskpro33のキーボードは永遠に使えないのだな(って手元にはあるんだけど)と時代の流れは軽薄短小へ(って、まさにキーボードのためにある言葉のような)とつくづく実感。
仮説や口頭説明は、詳細な生データのかわりにはなりません。
そのとおりだ。
というわけで、再現可能なものならばその操作の全事実を記録するための機能を実装したと仮定する。
ところが、その機能を有効にするとバグが発生しない。無効にすると発生する。だめじゃん。
でも、そうでもない。
そのように操作できるということは、完全な再現手段を知っているということだ(だから有効無効での発生の有無がわかる)。
したがって、再現可能な2つのバグを発見したということになる。
というか、こういう(ジャーナリングを有効にすると発生しなくなる)バグってのはスタックを破壊してるってことだろうな、と仮説を立ててみたり。
昨日の出費はでかかった(とは言え、コンタクトって卵ほどじゃないだろうが物価安定商品のような。しかもO2を透過できるようになったり機能は向上しているみたいだし)。しかし、デブサミの前にけりが付いたのだけは不幸中の幸い。
なーんか、サブクラス化したときエラーになる可能性があるから、無引数コンストラクタを書いておけとかあるのを読むと暗澹たる気持ちになるね。
設計として、引数ありと引数なしの両方の生成方法を考えたのであれば、定義するのは当然だ。
でも、引数ありのコンストラクタを定義して引数なしのコンストラクタを定義していない場合というのは、本来、必ず引数ありコンストラクタを呼べ(もちろんサブクラスであっても)ということを意味する。だから、
Parent.java class Parent { } Child.java class Child { }な状態から
Parent.java class Parent { Parent(Foo foo) { ... } } Child.java -> コンパイルエラー class Child { }
というのは、インターフェイスの変更を行ってしまったのだから、Child.javaのコンパイルはエラーになる「べき」なのだ。それによってChild.javaも修正しなければならない。
もちろん、従来の引数なしコンストラクタでの生成を認めるなら
Parent.java class Parent { Parent() {} Parent(Foo foo) { ... } }
とするのは当たり前であって、しないのは問題外で考えるまでも無い。インターフェイスの変更を行う場合、現状をどうするか(エラーか認めるか)考えてから行動するのは加算に+記号を使うのと同程度に当たり前のことだ。
それを闇雲に機械的につまり無定見に最初の時点から引数なしコンストラクタを定義したら、インターフェイス変更によってエラーになるべきChild.javaがまともな初期化なしに妙な動作をしてしまうことになるじゃないか。
もちろん、Parent.java class Parent { Parent() { } } → Parent.java class Parent { Parent() { throw new IllegalStateException("must call with Foo");} Parent(Foo foo) { ... } }
ってのもありだけど、コンパイルエラーにさせるほうが良いね。実行時まで問題の発見を遅らせても良いことなんてありはしない。
結論は、
1.インターフェイス変更はもちろん悪。でも設計当初には予測不可能だった問題によって変更せざるを得ない場合もあるから、その場合は大胆に変更。なぜなら、問題点はコンパイルエラーによって明らかにされる。2.無定見な引数なしコンストラクタの定義は悪。理由はインターフェイス変更による問題点の発見が遅れる。
ということだ。
でも、削除するって方法もあるね。引数ありを定義した時点で無引数コンストラクタを削除とか。
でも、無引数コンストラクタを省略しているってことは、記述すべき内容が無いってことでもある。そこで
class Foo { int foo = 0; long fool = 0L; ... } とか class Foo { int foo; long fool; Foo() { foo = 0; fool = 0L; } ... }
のような無意味な記述をするかどうかで切り分けるという考え方もできるかも。
ダブルスタンダードは悪の帝国の始まり。
というところから始めると、上のように無駄で無意味で冗長でまったく有意義じゃない記述をたとえば「読むのはJavaの言語仕様を知らない、つまり初期値はプリミティブはゼロ、オブジェクトはnullということがわからない人が読み書きすることを前提」として「記述必須」とするコーディング規約を作るなら、確かに「デフォルトコンストラクタを利用してはだめ。必ず空でも(というか、最初の規約からゼロ代入とかは普通あるだろうから空にはならんか)記述必須」とするのは理解できる。
理解はできるが、僕ならまずそのへんの仕様については知っていることを求めるけどね。少なくともソースを触らせるのなら。
さらに追記:ちなみにfinalで修飾した場合の取り扱いはおもしろいと思う。
さらにさらに追記:ここまでくると「オレはそれをダブルスタンダードではなくケースバイケースと呼ぶね」、ってのもありだと思うが。
お会いした方を列挙すると
Rubyな方々:まつもとさん、かずひこさん(おお、一目でわかったぞ)、助田さん(お久しぶりです)、咳さん、はんばあぐさん
アジャイルな方々:角谷さん、あまぴょんさん、t-wadaさん、大熊さん
謎な方々:dotさん、えがぴ〜さん、kdmsnrさん (2/6追記:コミュニティというかセグメントが見えないからで「謎」に深い意味はないです。kdmsnrさんはrubyなのかなぁというとそれも違いそうかなとか。かくいう私はなんでしょう?)
(でも、実際はかぶってるよ。たとえば咳さんはアジャイルな方々かも。でもやっぱりRubyのほうかな)
スターロジックな(というかSeasarな)方々とか。
もちろん.NETな方々。っていうか僕はここだったわけだし。中西さん、小島さん、三部さんとかね。
吉松さん(ファンだ。複数言語のマルチモジュールとか試した記事を@itとかに書いたりするんだぜ)の名刺いただいたり。というかはてなの作り方を読んでいたのが印象的。平鍋さんや河村さんに挨拶したり。
皆様、お疲れ様でした。えーと、小井土さん、福井さん、岩切さん、お誘いくださって本当にありがとうございました。
#自分のセッションが気になってあまり他のセッションを落ち着いて聞けなかったから感想は無しだったり。それにつけてもS2JSFってHTMLをそのまま利用できるようにしたっていうことだけでも素晴らしい。DIコンテナの1番の長所は、依存性解決そのものではなく、周りにいろんなものを追加していきやすい/くっつけやすい/そう考えやすい(多分、何か発想の転換がもたらされるんだろう)ことじゃなかろうかと思ったり。
追記:一応ここでも資料(パワポとVS.NETのプロジェクト)を落とせるようにしておく。
#さらに追記:今見たらMoreDICon#classRead(Moreって言っても超lesserだが)っていくらデモ用サンプルとは言えひどい点がある。1)foundでインスタンス化してもまだコンストラクタの探索を続けている。2)コンストラクタのパラメータには文字列とプリミティブしか認めていないけど、生成順と指定順が合っていればオブジェクトも設定できるはずだ(とは言えこれは長くなるからどっちにしてもやらないだろうが)。
全体的には配布用には解説コメントを埋め込むべきだったかも。
失敗した。
現象は、リブート後のインストールの続きでの文字化け。Englishを選択してもJapaneseを選択しても全く読めない。F2とかIPとかF6とかが読めてもだめだこりゃ。つまり、2回インストールしている。1度目はJapaneseを選択してそうなったので、2度目はEnglishを選択したということだ。しかし、Englishを選択したらEnglishで出してくれれば良いのに違うとはこれいかに(これはバグだろうな)
でも、みた感じそんな指摘はどこにもないな。
ってことは何か特殊なことをしたらしい。
可能性としては、PCKをデフォルトにしたことだろう。
ただのjaでやり直してみるか……
あと、昔懐かしいSMCのネットワークカードを認識していない雰囲気。手元にはDL10030があるが、こっちに変えればOKかな?
と思ったらSMCのEIIはあるな。こっちは何がまずいんだ?
追記:どうやっても初回はそうなるみたいだ。途中で電源落として再起動したらすんなりEnglishになったということは、インストール時はEnglishを選ばなきゃだめだ(というかコンソールモードだからだなと気付くのが遅い)ということだ。
しかもインストール完了後はNICも認識してるというか、ちゃんとDHCPサーバからアドレスとか取り込んでるし。
まあ、基本的には1度しかないインストール時の動作についてはこんなもんかな。さて、Creatorとか入れるか。
rm /usr/bin/tar ln -s /usr/sfw/bin/gtar /usr/bin/tar ln -s /usr/sfw/bin/gar /usr/bin/ar ln -s /usr/sfw/bin/gmake /usr/bin/make ln -s /usr/sfw/bin/gcc /usr/bin/cc #必要に応じて。いずれにしろ/usr/sfw/binと/opt/sfw/binにPATHを通すことになる。あと、sudoersは、/opt/sfw/etcの下。
どこにも行かず、あるところにはあるんだろうけれど。
SqueakってLOGOの代わりにもなるんだよね、と思っただけのことなのだが。
それまで生産していた子供が気付くと消費をするようになる、その年齢的な分岐点ってあるんだろうか? わけのわからない絵を書いたり妙なお話を作って喋ってたりしているのはそれはそれで生産なんだが、本を読んだりゲームをしたりするようになるのはそれは消費だ。
文化(笑)の自給自足からの脱皮って、つまらんな。
絵を書くのなら紙(壁かも知れないけど)とクレヨンなりは消費する。妙な絵本を書いている時もそうだ。お話を喋ってるときはほとんど消費しないけど。時間くらいか。
いずれにしたって消費はするもんだ。でも素材を消費するのと完成品を消費するのは偉い違いだ。
限界を子供ながらに悟るってのはありそうだ。その限界が技術的な限界なら(たとえば絵や物語だけだったらそりゃ本職の漫画家のほうがうまいわけだし。)、そこをコンピュータが補助することはできそうだ。
というようなことをぼんやりと、アラン・ケイ氏に聞く「コンピュータで子供に何を教えるか?」を読みながら考えた。例によって書いてある内容とはあまり関係ないのだが。
僕が小学生の頃、家庭科は料理を作ったりなんだか忘れたけど縫ったりすることを教わる時間だったし、中学生の頃の技術は旋盤でハンマーを作ったり(まだ持ってたりするのだが、結構重宝する)、板金でチリ取りを作ったり、木工で本棚を作ったりする時間で、これは素材は消費するが生産だった。
そういった技術の時間に、コンピュータを使いながらしかしワープロの操作を教えるってのはやはり違うような気がする。別に旋盤を回せとは思わないが(でもあれはあれでおもしろい経験だったが)妙な違和感を覚える。ワープロを使って作れるものは文書でワープロそれ自身とは全く異なるものだ。でも、旋盤で作ったものは板金のための道具だったり、板金で作ったものは掃除のための道具だったり、道具で道具を作るというサイクルがあった。
だったら、コンピュータを子供に教えるなら、それはプログラミングじゃなきゃおかしいじゃないか。プログラムで作ったものはプログラム、そのプログラムを使って何かをするというように道具で道具を作るというサイクルを経験させるっていうのは重要なことに思える。それを変えるってことは技術の本質的な何かを失わせてしまうことなんじゃなかろうか。
それはいやだな、と思う。
近況を読んでいて、そういや、2つのスピカと引き続きピース電器じゃなかった白熊ピース嬢を録画したのであったと思い出した。うまく時間がずれていて良かった良かった。
さて、届いたのでまずは監訳者のことばを読む。あ、まさにLOGO→スモールトーク→イートイズだったのか。と書いて気付いたがなんでLOGOはロゴじゃなくてスモールトークはSmalltalkじゃないんだろう。読み物だからかな?
で、次はアランケイの後書きだ。
うーん、読み始めてから幾らか引っ掛かる点がないわけじゃない。気候変動よりもサーベルタイガーに興味を惹かれることを「思考力の弱さや欠点」とみなすのはどうなんだろう? なんとなくカチンと来るのは、オレが物語が好きだからだ。そりゃ大きな物語が生き残っていた時代に育ったわけだし、物語は常に横にいたわけだが。とは言え
人はなぜエセ科学に騙されるのか〈上〉 (新潮文庫)(カール セーガン)
同じような主張でも、これが『星間空間を漂う冷たくて希薄なガスの中に、生命の構成要素である分子が存在すること』と『ノストラダムスの予言』の対比だと違和感は無いんだけどね。
でも、名前をつけるな、というのはいろいろ感じるところがあった。確かに名前をつけるということは知ったつもりの思考停止の最初の1歩であるな。偶然だがセーガンからの引用がまさにそうだ。名前がつかないもの(存在すること)と名前がついたもの(ノストラダムスの予言)か。
でも確かにそうなんだ。
その一方で名前で思考停止とか聞くと、反射的に「税金」とか「年金」とか「著作権」とか「知的所有権」とかいろいろな名前が浮かんでくるところが物語の始まりでもあったりして。名前があると確かにそこに不動ものとして存在するように見えてしまうもんだからな。古くは「王権」とか「神」とかだ。とどうしても人間が作った制度というか物語に興味が向くのが思考力の弱さというものかな。
で、久しぶりにイートイズを動かしてみた(とは言え、『子供の思考力を高めるスクイーク』とは無関係にカマンベールのほうを見ながらだが)。ハロの出し方がわからなくてうにゃうにゃやっていたら子供は覚えていたりしてちょっと驚いたり。でもそれはそれとして以前教わったことは覚えていたから最初に部品の位置を調整して保存したりはしたけど。で、Mac版だと、アプリケーションとしてインストール(と言ってもフォルダを配置するだけだが)すると、保存時にディレクトリが配置ディレクトリしか選べなくてエラーになるが、まず書類フォルダを見て欲しいなと思ったり。
追記:
今気付いたが、気候変動とサーベルタイガーはつながりがあるな。もしかすると気候変動を扱った映画かドラマがあってケイはわくわくしながら見始めたら、なんのことはなくそのせいで右往左往して生き延びようとして頑張るサーベルタイガーの親子の物語かなにかでがっかり/うんざりしたのかも。と、常に物語をこしらえるわけだが、それがないとイマイチつまらんなとやはり思うのであった。
何が起きるか良くわからないままPen new dragon:10して、?となったため、ついPen new dragon: 100とかやってしまって返って来なくなったり。
#コマンドコンソールの出し方がわからなくてとりあえずデバッガに入ってやってみたのだった。(Cmd-Dに対応するブレーク方法を調べてから動かすのが筋ですね。Squeakに関しては完全に子供モード――とりあえず試す――で動かしているなぁ)
首の筋肉が死ぬよりも痛い。目薬さすのに上向けない。枕が高くて痛い、無ければもっと痛い、低けりゃ低いでやっぱり痛い。
というわけで、ちょっと見かけたCDのニッパチ法則を手元で見てみたり。あさまししまくるぞ。
がーそ、早速在庫切れだ。でも2番がハ短調、8番がホ短調。すっげえ傑作じゃん。特に2番はインベンションの最高峰だ。わざとよれたりもつれたりしながら何回弾いたことだろう。わざとやんなくてもよれたりもつれたりするけどそれはそれだ。
というわけで、高橋悠治は4度ずつ上昇させる戦略で順序を変えている(ちなみにグールドも微妙な順序の変更をしている)。
でも、バッハでニッパチの検証はフェアじゃない。
で、ちょうどさっきまで眺めていたサイケデリックファーズだ。しかし、本当に三流モノマネバンドだな。サイケと毛皮か。でも、声は良いしサビの作り方は一流だ。
2曲目はプリティ・イン・ピンクだから文句なしの傑作で、こんなかっこ良い曲はなかなか生まれないだろう。でもまあ8曲目は……
ちなみに同名の映画は見たこたないが、アマゾンの評だと「多分、くそ映画のプリティインピンクが出自かも知れないけど、許す、すべてを許す。」という調子で誉めているが確かに名曲だ。
で、丁度iPodから流れてるからボウイだ。
2曲目はソウルラブ。うーん、悪くはないけど。でも8曲目はパンク縦揺れの前哨戦のようなハングオントゥユアセルフで僕は好きだな。
チャイナガールは言わずと知れた傑作だけどそのプロモーションのためかシリアスムーンライトツアーのビデオで最前列の中国女がやたらとめだっていたが。マオマオマオとメロディーが出てくるほうがYMOのやつより先に立つのはまあしょうがなくて、どちらにしてもボウイは3番手だが。で、8曲目がふがふが気が抜けたシェイクイット(ベイビー)……。でも意外なほどレッツダンスでは4曲目と8曲目の脱力ぶりが好きでもある。
でも、これは法則通りかも。全然アンノウンじゃないな。でも、こっちはどうだ。
アイソレーションとエターナルの看板ナンバーが2と8だ。
ま、どうでもいいや。
これがオイラか……
大きな仕事や伝統的な技術などに向いている性質です。またとても変わった自分なりの法則・理屈・観念を持っており、それにしたがって行動します。しかしそれら理屈は考え方が独自のものなのでなかなか他人には理解されません。
肝に銘じておくとするか……
邪神占いより。
ラブクラフト全集の復活に心を動かされた者はやるべきだろうか?
どうでも良いが思い出したブラッドベリ。うろ覚えによる再構成。
図書館にて
主人公:で、ラブクラフトはありますか?
若き女性司書:(顔を赤らめて)そんなものは置いていません……
大島さんの日記からmixi(友達の友達なのか)経由で。
追記:ラグクラフトって……ちょっとそれは……
_ sumim [うっかりしておりました。終わらない処理を中断するには cmd-ピリオド を押してください。現われたピンクのウインドウ..]
</html>が無くても処理するブラウザーが悪いというわけにはいかんのかな。って言うかきっと逆に進むんだろうけど。(想定しているのは、コンパイラのストリクトさとかなので)
int a int b = "a"で、
;
が無いというのは多分判定可能だ。
String a = "aaa" + "bbbb"
大丈夫そうだな。"
についてはいささか微妙な感じだけど。でもそれって文法違反を認めるってことだな。スピード違反みたいなもので虫の居所とか、査定とか、目にあまるとかの恣意性でもって違反の判定を下すようにするってことだ。
これって、法治に逆行することなんじゃないか。3000年前に韓非子が法治をもって人治に対峙したのは、権力をもつ人間の気まぐれや恣意(孔子の流儀で言えば徳とか仁とかだし、その実体は情とか勘とかだ)で人が裁かれることがないように法という規準を設ける――つまり権力が合理性をもって振舞うように枠組みを作る――安全な体制の確立なのであった。でも、結局はそう固くはできずに現在の世界があったり。
ある意味、科学に通じることであるな、とか。
話題からはずれるけど(Javaだと思うから)、C#だとC#での型名stringと、CTSのクラス名System.Stringと同一のものに2つの名前があるからどっちを書いてもOKだったり。
逆の資料はMSDNでも見つかったのだが、EntourageからOutlookへの方法が見つからない。
どうも、Windows→Macってのは一方通行のようだ。
Squeakによる変化ヲ抱擁セヨ、コーステキスト。
Emerging Technologiesって、日本語にすると、技術の勃興とか、うんと意訳して新技術解説とかって意味なのかな?
コースのテーマは「変化」。3本柱はリファクタリング、XP、Squeak。なんとなく時期といい(2001年)、ちょっとビジネスのメインストリームから外した言語といい、Ruby256倍の極道編を思わせなくもない。
#Squeakの使い方を調べていて行き当たった。
コンパイラにバグがあるならば、C++のほうが良い言語と言える。アセンブラリスト(アセンブリリストのような気もする。アセンブラが出力したリストか、アセンブリのリストかどっちだろう? Googleでカタカナで検索すると3:1くらいでアセンブラリストだな)を見れば一目瞭然だし。
でも、それは本末転倒な理由だな。
patchと書かれたファイルを見たらdiffが入っていて面食らった。そしてpatchというコマンドを見つけて非常に不思議に思った。
patchという言葉が知っていたものと意味が異なったからだ。
Cで書いてもしょうがないが、最初に覚えたpatchはこんな感じだ。
static unsigned char patch[512]; ...で、例えば
void foo(int x) { printf("%d\n", x * 2); }という関数fooにパッチを当てる(たとえばxを3倍する)とすると、まずpatchに相当するアドレスを探し、以下のコードをアセンブルしたものを直接書き込む。
printf("%d\n", x * 3); ret // なんてCには無いけど次にfooの先頭アドレスを探し、以下のコードをアセンブルした結果を書き込む。
goto patch;
というように、メモリーイメージを直接いじくるのが最初に知ったpatchだったからだ。ところがある時点でpatchというのはソースファイルをいじくるものを指すことが(コマンドになってるくらいだし)普通らしいと気付いたのであった。
そう言えば/dev/kmemが大好きな人もいたな。
今ではこういう技術はexploit研究家だけのものになってしまったのかな?
そんなことは無いだろう。でもあまり使われることはなさそうだ。
全くもって他人事なのだが、興味深い。
と思ったら、ちゃんと追ってないのであれだが全くの他人事というわけじゃない(eToysユーザーではあるわけで)のかな?
――大島さんの日記経由。
#やっとテストの使い方がわかってライントレーサーを実装してみたり(カマンベールの本をそのまま――ラインだけを判定――じゃつまらんので、境界を判定するようにしてみたり)。おもしろいな。
デリゲートの使い方になぜかなってしまったが、僕は直定数は読みやすいから好きだという(か、おまいら定数の定義をし過ぎという)のが発端の文章。
思い出したがCDocTemplateというかRUNTIME_CLASSマクロってのがあったな(これ自身は文字列そのものとはちょっと違うが)。
頑張れば「簡単に」できると言えなくもないかな。
別にそんな気はないのだがヲチ対象化してしまっているsqueakerさんのところから。
Blogとして書いてあるからだろうけど、僕にはすごく読みにくかったが(っていうか技術文書しか読めないわけだし)でもこれだけおもしろいととにもかくにも読んでしまうもんだ。
内容は、ゲームシステム(ゲームそのものじゃない)に興味と熱意を持って、圧縮したり高速化したりして、途中でMacに出会って、ついにコロニーを出すにいたる(その後もあるのだが、って言うかその後(Croquet)が重要なんだろうな)までの波乱万丈の物語。
グリーンブラットを手伝ってLMIで働いていたから(っていうか、こういうエピソードだけで掴みは十分だよな)、当然のようにその頃ストールマン――Symbolicsハックをしてた頃だね――にも出会ってた。ソフトウェアとフリーについて論争したり。で、その後Macワールドの会場前でビラを撒いてる(多分、例のルック&フィール訴訟のころだろう)ところに出くわしたがストールマンは自分を覚えていなかった。Yet another humbling experience.(とくるから、読めないわけで、どう訳すのがぴったりくるんだろうか? 「まあ、つまらん話ではあるな」ということなのか、「内心忸怩たる思いであった」という感情を含むのか、「どうでもいいけどさ」とサラッとしたものなのか、僕の英語力ではわからないわけである)
そうそうあるある話――FD入れて起動して、FD入れてデータ読ませて、FD入れてシステムへ制御移して、FD入れて……とか。
「こいつはすげぇ」とゲームプロデューサに認められて(そのゲームシステム――ゲームエンジンと訳すのが正しいのかな――が)で、VPに紹介されると「で、ゲームそのものは?」と聞かれてボツになるとか、「こいつはすげぇ」と次のゲームのエンジンとして採用が決まったがシナリオがテリブルで(だけじゃなくて財務状態そのものが原因かな)消えてしまったり(スペクトラムホロバイトのゲームって、何かAmiga用のフライトコンバットものを持ってたな、そう言えば)とか。
で、ゲーマーがすぐに解いてクソゲーとか言うんじゃないかというプレッシャーから死ぬほど難しく作ったとか、いろいろ。
赤毛(同じ主演者の赤ひげより遥かに好きだ)
大誘拐 (双葉文庫―日本推理作家協会賞受賞作全集)(天藤 真)
(これは原作も滅法おもしろい)
かな。僕が映画館で見たのは(赤毛は最後の20分くらいを池袋文芸地下で見ただけだが、すごく印象的だから見たうちに数える。三船敏郎が官軍の大群にたった一人で説教垂れるところはジャッキーチェンみたいに圧倒的に優位な立場で垂れる説教シーンとは異なり、ばかばかしいほど感動的であった)。
からす組〈上〉 (徳間文庫)(子母沢 寛) (買っておいて良かった。絶版なのか)
以前、歴史読本の質問コーナーで、からす組の映画を撮りたいから資料を教えて君投稿をしてたが、結局映画の夢と終わったのか。僕も見たかったよ。天狗党とかからす組とか彰義隊とか、あの人が撮るべき題材は赤報隊以外にもたくさんあった。困民党もそうだな。226だって告白的な人ではなくあの人にこそ撮って欲しかったな。
あまり見る気がしない告白的な人は全集が出ているのだが。
なんか訃報を読んでると肉弾を「特攻隊員」の物語としてるのを見かけたが本当なのか?
見ていない(ATGとかさ、それほど見たかないよな)ので文句をつけるのも変なんだが、あれは、特攻は特攻でも人間魚雷要員の少年兵が結局魚雷が不足しているもんで、ドラム缶に爆弾と一緒に詰め込まれて太平洋でぷかぷかして敗戦の後にどこかに白骨になって流れつくという物語じゃなかったっけ?
違った。やっぱり見ないで語るのは落ちるな。でも単純に特攻隊員の物語で済ませられるわけでは無い。普通、そう書いたら紫電改のタカみたくなるだろう?
ちゃんと調べろよ、人が死んでるんだから。>毎日新聞
(東京新聞/日刊スポーツだと『終戦時期の青年をコミカルに描いた』……になっているな)
辞書をひくと卑下とか質素とかつまらない(おもしろくないの意味ではないほう)とか書いてあるので意味が掴めなかったが。
よしきさん(興味深いコンテンツをいつもありがとうございます)のご教示で、「あ、IMHOのHなのか」と気づいた。そうか、卑下と謙虚じゃ全然違う。卑下は実際には相手を見下しているのだが、謙虚は自分が何者であるかをあらためて見直すことだ。
で、なんとなく思ったんだが、よくある文化論みたいなやつだと『日本人の』謙譲の美徳みたいな物言いってあるけど、仮に単なる決まり文句だとしても(というかそれだからこそ)IMHOとか僕の2セント(たぶん、「取るに足らないけど」というニュアンスが含まれているんだろうと思う)といった言い回しがあるわけだから、もちろん『日本人』固有の意識ってわけはないだろう。でも、そういう謙虚さについての物言いが一定の了解事項として考えられてるってのはどうしてなんだろう。ある種の人々の間にだけIMHO的な意識があるのか、それともある領域を共有している場合に限りそういう言い回しがなりたつのかな。
#っていうか、謙譲の美徳ってのは、上で書いている卑下のほうで、謙虚さとは別の概念なのかな。
スレッドを使い捨てでばんばん作るサーブレットコンテナを使うんだったら、ThreadLocalはあまり意味がない(だって、ThreadLocalに保存しても2度目はないわけだから)。というかオーバーヘッドだけがある。
でもサーブレットコンテナがスレッドプールを使うかどうかは実装に依存している。
ってことは、ThreadLocalを使うかスタック(たとえばdoPostとかの中で)に作るかを決定するのに、サーブレットコンテナの実装詳細を知る必要が出てくるわけだが。
別の戦略もある。
ThreadLocalのかわりに自分でプールを作る方法だ。LinkedListが本来だけど結構重いから開き直ってArrayListでもかまわないけど。
List freeResources = new LinkedList(); public void init(ServletConfig cfg) throws ServletException { super.init(cfg); for (int i = 0; i < Integer.intValue(cfg.getInitParameter("nrOfResources"); i++) { // あらかじめプールする場合 freeResources.add(new FooBarResource(cfg)); } } .... public void dpPost(...) { FooBarResource fb = null; synchronized(freeResources) { if (freeResources.size() > 0) { fb = (FooBarResource)freeResources.remove(0); } // 後からプールを作成する場合にはここで作っても良い。 } if (fb == null) { resp.setStatus(HttpServletResponse.SC_SERVICE_UNAVALIABLE); return; } try { .... } finally { synchronized(freeResources) { freeResources.add(fb); } } } public void destroy() { for (Iterator i = freeResources.iterator(); i.hasNext();) { ((FooBarResource)i.next()).cleanup(); // クリーンアップが必要な場合 } freeResources.clear(); }
ThreadLocalよりちょっと有利なのは、後処理が素直に可能な点。後処理が必要なリソースの場合、ThreadLocalを使っても結局、destroyでクリーンアップするためにどこかに全部がめておかなければならなくなる。
1997年だと思うんだけど、もちょっと早い(ってことはないだろう)かも。
どっちが早いかは微妙だけど、とある協議会とDCOMのメーリングリスト(と言っても読んでるだけだけど)のどっちかでXMLが話題になりつつあったのであった。実装としてはIE4の最初のXMLパーサが出現したころだ。
で、DCOMのMLのほうでは、ジョナサンボーデンってやつがSMTP上でXMLを利用したRPCについていろいろ書いていた。で、COMの型のシリアライゼーションとか、それに対してDCOMでいいじゃんとかいう意見とか、IISのDCOMプロクシ(名前忘れた)がバギーだとかいろいろあったりしたのだが、
・HTTPのように、TCP/IPの上の非常に薄いプロトコル上に乗っけたアプリケーションプロトコロル
・データは文字列ベースでかつパーシングが簡単か、不要
ということを自分が関係するソフトウェアの通信インフラとして考えていた僕は、ジョナサンボーデンのアイディアがすごく気に入った。
最初の点はブラックボックスを可能な限り薄くしたいということだ。本当はUDPが良いのだが(とその頃は信じていたし今でも時々は思う)、どうも再試行のアルゴリズムをどうやっても輻輳が起きてしまう(再試行の再試行の再試行に対してNAKが出てきて再試行してのような状態)という問題があったので、どうあがいても問題があるのなら、何も考えずにTCPの実装に任せてしまえというのもある。で、TCP上に乗せると決めればデバッグツールとしてブラウザ(サーバー側にとっては)とIISみたいなサーバ(クライアント側にとっては)が出来合いであるわけだから、HTTPをその上に被せれば良さそうだとなった。
で、データをどうするかだけど構造が複雑だったりするからバイナリをいろいろいじることも考えたりもするわけだが、プロトコル決めるところで出来合いのものをデバッグ用に使おうとしているということから、あまり外れたものじゃ具合が悪いな、CSVってのはネストした構造を表現するのが大変だし、とか考えていたところにジョナサンボーデンのアイディアがあって、そうかXMLか、と納得したのであった。それに確かにXMLであれば、要素を決めておけばオレ様RPCの実装も極めて単純に済む。全部文字列だからVBScriptみたいなへっぽこ言語(今はそんなにへっぽこじゃないけど、その頃はとてつもなくへっぽこであった)でもテスト用サーバアプリケーションくらいささっと書けるし、それでいいや、てな感じだ。
つまり、HTTP+XML=オレ様RPCという公式は、あの頃、誰でも考えていた。で、大声で先頭を走ったのがXML-RPCで、がつんがつんと製品として規格化をやっていったのがSOAPだということだ。だからSOAPは最初はMSのオレ様ORPC(COMのデータ型だけ考えてた――XDRを使って――で、BizTalkに雰囲気が残っていたり)でその後にIBMが入ってきたりしてまっとうなRPC(ORPCではなくなっていたり)の仕様となる。その一方、辺境の地で僕はオレ様の世界で走り出していた。
ちなみに、RPCのインフラとしてHTTPを実際に使うとなると、ネイグルアルゴリズムやらHTTPサーバ側のバッファリングだとか、コネクションのキープアライブだとかが出てくるのだが、そういうものは最適化するときに考えることにすれば良いので無視。
というようなところから出発したもので、僕にとってはスキーマはオレ様スキーマで良いというか、そもそもスキーマは本当にメタなところにしか存在しない。だからXDRも、XML-RPCも、無視だ。だってどの要素がどの型かはスキーマ(DTDで十分)を切った時点でわかってるわけだし。その仕様に影響されるのはオレ様の世界だけだからね。
当然、そんな時期に実装したわけだから、スキーマコンパイラなんて気の利いたものはまだ存在しないから、自分でIE4のDOMをベースに実装することになる。だいたい、IE4のDOMだと空白の扱いや大文字小文字の扱いがVBルールだったりしたからどうにもならんのだな。で、さらにIE4を乗せられない箱もあったりするわけで、しょうがないので、IE4のDOMとAPI互換のCOMのDLLを作ったり。さらにIISが乗らないボックスがあって、これもしょうがないのでVBScriptをホストする(これは、IE3.2が乗っていればくっついているわけだし)VBScriptから見たらIIS互換のHTTPサーバをでっち上げたり(ということは、このサーバに関してはNT4のOption pack以降のことだからもっと時期は遅いな)。このオレ様HTTPサーバ(ASP互換もどき)は結構重宝した。
で、それがレガシーになったから、SOAPが出てきてもスキーマコンパイラが出てきても、ほとんど関係がなかったのだ。というか、SOAPに合わせる必要性も必然性もないし。とは言え、本当は使えるものは使いたいのだが、どうしようもなくNT4SP4のままの箱とかがあったり、IEのバージョンを4以降にできなかったりする箱が残っている限りはどうにもならんな、という側面があったのも事実ではある。で、MSの世界とは言え、まさしく異機種混交なので(IE3とIE4、IISの有無、その他もろもろ。最後にはNT3.51やCE2.xまで相手にした)、HTTP+XML=RPCは確かに良い選択かも知れない。使えるところではIISや(まともになった)DOMDocumentが使えたのも事実だし。
で、結局1999年までにはそうやって直接パーシングする文化がチームに根付いてしまった。当然、スキーマコンパイラを使う習慣がチームに無いってのがいろんな意味で開発の方向を決めてしまう。だって、スキーマコンパイラの仕様を調べなくても自分でパーサいじれば何でもできてしまうわけで、ある意味、非常に効率が良い。スキーマ定義も人間が了解できれば良いわけで(ということはバリデーションも使っていなかったり。というのはパーサがそのスキーマを非サポートだったりする場合もこれまた異機種混交なのであるからだ)いい加減なものだ。そんなやり方だから、21世紀になってスキーマがDTDからWXSやRELAX NGに変わっても(というか、好き勝手なスキーマを各自がいろいろ使っている時点で統一もへったくれもないが、僕はそれで全然OKだと思っている)相変わらずSAXやらDOMやらを直接いじくるのが主流であったり。さすがにそろそろスキーマコンパイラくらい使おうぜと幾つか使ってみたが、既に技術基盤として直接パーサとインターフェイスする文化があるからどうやっても、汎用ってのは汎用だよね、という結論にならざるを得ない。結局、自分で書いたほうが早いし、きめ細かいし、微妙な調整が可能だし。っていうか、SAX好きだし。で、相変わらず人によってDTDでスキーマきったり、WXS使ったり、RELAX NGだったりばらばらだったり。
というわけで、限りなくボヘミアンにやっているのが実情だったり。
#だから、SOAP一押しと言われても、ちょっと微妙かな。.NETヘテロ(何書いてんだか。逆じゃん)だけのシステムであだったりすれば、文句なし一押しではあるけど。というか、そういうシステム(もあるわけで)では当然のようにそうなんだけど。特にVS.NETを開発標準とすれば、スキーマコンパイラを意識する必要すら無いし、スキーマはお絵かきで書けるし。で、選択の問題としても、多少の速度遅延があっても(むにゃむにゃ)Remotingや相変わらずなDCOMみたいなむにゃむにゃを使うなんて危険なことはできないわけで、当然のようにSOAPを使うことになる(XMLデシリアライゼーションが遅い? そんな時は直接パーシングで決まりだ)。
というわけで、Indigoが楽しみだ。
なんて書いてあらためていろいろ巡回してたら、sumimさんがRubyとIndigoとSmalltalkが並列している妙な引用を書かれていた。
で、読みに行ったらドンボックスがRubyを学ぶべき(またはSmalltalkを学び直す)時が来たれりとか書いている。で、静型付け言語とIDE――これが無ければダメダメよ、というコメントが付いていて、さらにYoshikiさんがちょっと妙な反論(JavaにしろC++にしろ未宣言のインスタンス変数はエラーになるからその点が妙だ。C++だと未初期化のローカル変数がらみのバグはありえるからその意味かな? それにリファクタリングしてそんなエラーが入るってことは有り得ないと思う)をしていたり。でも主張はわかる。どっちも。
それにつけてもドンボックスは、オブジェクトからメッセージ(でも、Indigoのメッセージって抽象的なメッセージじゃなくて物理的なメッセージだと思うんだけど違うのか?)に転進を遂げたんだったな。
いずれにしろ、オブジェクトであろうがメッセージであろうが、仕様のバグを前にすれば、どちらもバギーなプログラムとなることだけは事実だけど。
ってのは(と上から続いて)、こないだ子供がほととぎすを覚えて講釈垂れてたとき思ったことを思い出したからだ。
――鳴かぬなら殺してしまえほととぎす
この信長の功利主義は嫌いではないし、
――鳴かぬなら鳴かして見せようほととぎす
この秀吉の志の高さも嫌いではないし、
――鳴かぬなら鳴くまで待とうほととぎす
この家康の将来展望(もちろん、鳴くという見通しがあるのだ)の遠見明察ぶりも嫌いではない。
でも、自分のスタンスを考えると、この3個のどれでもないんだな。
――鳴かぬなら作ってしまえほととぎす
やっぱり、こうだろう。
(ちなみに、ほととぎすに限定すると、鳴かぬなら誰かが作るだろうほととぎす、と家康の将来展望に近いスタンスになるわけだが)
_ kahei [昔々に友人がこんなことを言っておりました。 鳴かぬなら自分で鳴こうほととぎす]
眠狂四郎も、死にたいやつは死ねばよいのだと言ってることだし(机龍之介かも知れないな)。
わからない人には、ぐちゃぐちゃ引っ張ったりnewしたりしなくて良いから、コンストラクタに並べとけ、とか、セッタ作っとけ、で済ませるってことはできると思うんだが。そこで「なんでそれで良いのか?」って聞いてくるんだったら理解できないはずはないんじゃなかろうか。
ってことは、C++みたいに明示的にfreeしなきゃならないような言語ではより効果的に使えるかも知れないな。と思ったがメタデータが無い(マクロ使って埋め込めば良いわけだが)んだなこれが。
3文字英語略語なんて理解できないですな。
たとえば、MFC、COM、OLE、OCX、VBA、VBX、ASP、ADO、DAO、RDO、SQL、DDE、RPC、TLS、DLL、EXE、CON(これは関係ないか。でも理解できないよねぇ、こいつは)、MTS、API、HTM、PIF、VxD、TCP、UDP、IDL、MSI、GINA(残念、4文字だ)、WMI、WFC、AFC、まだなんかあったけな? とか、(追記:でたらめなやつと、DOSから始めてWindows NTとかを手にして初めて知った人がごっちゃにするようなやつ――TCPとか――の乱れ打ちなのでまじめに取ってはいけないけど。MSIってメインボードメーカだし――って言うことはなくてMicrosoft Installerだけど)
(なんか言った覚えもあるような)VBプログラマにCOMとただのDLLの違いやOLEとDDEの違いなんてわかるわけないじゃん、あいつらバカばっかだから、とか。
どこに行っても、いつになっても、それほど変わらない部分があるのはおもしろい。
DIってのは、JCPが出してきた言葉/方法論じゃない。
Windowsの世界で、そういうのってあるだろうか? MBV(なんだ他にもうじゃうじゃあるじゃん)、UDT、STA、MTA、NTA、ATL(3文字略語には他にもODLってのもあった。AFXとかDDXとかも。列挙したやつとは無関係だが)あたりはともかく、GITの出所は純MSじゃないような気がするな。あと、IDispatchデリゲータとか。デュアルもちょっと違うような気がする。WTLも最初はMSじゃないような気がしてきたな。
でも、それこそこのあたりは趣味の世界だということは否定できない。(で、当然のように趣味人は優雅に過ごすことができるわけだ。それとも、優雅に過ごすから趣味人なのかも。)
ところがGITに比べればDIなんていうのは極めてわかりやすいし誰にでも使いでがあるわけだから、一見似たように見えるが(構図は同じだが)、やっぱり違うように思う。
kdmsnrさんのクリップ経由。
で、思い出したが、純単体テストってやってないのかな? と。
DIコンテナ(であろうがなかろうが。たとえば意味合いは相当ずれるがファサードだって良いわけで)を利用するということはバカが逝くで最近試行錯誤されているように、テストを簡単にするっていう意味がすごく大きい。
でも、テストって一言で言ってしまうと受け入れテストとか負荷テスト(マシンハンマー=MCハマー)とか猫ピアノテストとかが入ってきたり、用語の差があったりして厄介なんだが、あくまでも単体テストなんだが、実はこいつも、ではデータベース(が曲者なのだが)と接続しないで単体テストと言えるのですかとか真顔で聞かれてもちょっと困ってしまうわけで、そこで、TDDという3文字略語で済ませられればいいのだが、動作を検証しながらプログラミングしましょうね、ということだから、もういっそテストとか言うと誤解を受けるから、ダックタイピングというのはアヒルがとにかく突っついてみるってことから命名されたということを援用して(でもダックタイピングについては実は大きく間違って僕が読んでいるかも知れないからまったくもっての見当外れかも知れないけど)ダックプログラミングとか呼んだらどうだろうとか、つまるところは開発のスタイルのことである。
突然、野坂昭如の息の長い(=「。」を打たない)文体を思い出したが書いていても疲れるなぁ、ハァハァ。
で、『DIへの途』の例はなかなかうまいので内容を真似してDIを利用してプログラミングするということを書いてみる。でも、内容はくそまじめだが書き方はよたよたふらふら夾雑物をじゃかすか入れて書いてみる。だからそのままここ読めじゃ通用しないから必ず自分で内容を咀嚼するよろし。
/** * 生鮮食品用の価格を照会するクラス。 * 午後6時を過ぎたら(以降だよ)無条件に5割引きだ。 */ public class FishPricePicker extends PricePicker { /** * 値段を返す。日本だし、別に不動産を扱うわけじゃないからlongで * 良いのだ。って言うか生鮮食品ならshortでも十分かも。 * @param itemCode 商品を示すコード * @return 値段。 */ public long getPrice(String itemCode) { long price = super.getPrice(itemCode); Calendar c = Calendar.getInstance(); if (c.get(Calendar.HOUR_OF_DAY) >= 18) { // このプログラムの仕様で18:00って言ってるわけだから // (それが証拠にクラスのJavadocにもそう書いてある) // こんなのは直定数で良いのだ。 // 条件節を読んだとき、他の何も参照しなくても条件が // わかるように書くほうが読みやすいぞ。 price /= 2; // 切り捨てご免 } return price; } }
なかなか自己主張が強いクラスだが、これを例とする。
このクラスはいきなり歩けない(とアヒルにこだわってみたり。っていうかダックタイピングのダックって本当にそういう意味なのかなぁ)。何しろスーパークラスには依存しているは(たとえばスーパークラスは当然のようにデータベースを読んで値段を参照するだろうし。するとデータベースに登録されていないitemCode
を与えるときっと例外とかになるだろうからこのクラスの割り算処理とかはテストできないだろうし、っていうかこのプログラムを作っているPCからデータベースにつなげられるのかどうかとかいろんな問題がある)、プログラムしている時刻にも依存しているは(18:00過ぎない――過ぎるって言葉はそれを含まないと思うんだけど、それでは以降の意味の言葉はなんだろう?――と5割引きのテストができないってことだな。またはいちいち時刻をコントロールパネルから変えるのか?)で、どうするのよ? という話だ。
こんな単純なプログラムだからコンパイル通ったらいきなりリリースでしょ、というのは、確かにこれくらいだったらありかも知れないとか思わないでもないけどそれは例だからで、やはり動かしながらプログラミングしなよ、そのほうが差し戻しとか無くてハッピーでしょ、お互いに。
って言うか、いきなりPricePicker
がインターフェイスじゃないのが問題なんだが。なんで問題かはとりあえずおいておいて、このまま、動かしながらプログラミングできる形に変えていく(コメントは省略)。
public class FishPricePicker extends PricePicker { PricePicker innerPicker; public FishPricePicker() { } public void setPricePicker(PricePicker newInnerPickder) { innerPickder = newInnerPickder; } public long getPrice(String itemCode) { // 実行時にバグれば最初の行でNullPointerExceptionで死ぬ。 // 異常なら正しく死ぬ場合には不変条件の検証のみで良い。 // (DBを破壊してから死ぬような場合にはやはりちゃんとチェックしたほうが良い) assert innerPicker != null; long price = innerPicker.getPrice(itemCode); Calendar c = Calendar.getInstance(); if (c.get(Calendar.HOUR_OF_DAY) >= 18) { price /= 2; } return price; } }
っていうわけでデコレータ(追記:わけわからん)元のPricePicker
を利用するように変形する。これでPricePicker
が依存していたテーブルとかデータベースとかからまずは解放されたわけだ。っていうのも次のプログラムをどこでも呼べるように本来的にはなる。
public class FishPricePickerTest extends TestCase { FishPricePicker fpp; protected void setUp() throws Exception { fpp = new FishPricePicker(); } private class MockPricePicker extends PricePicker { String itemCode; long testPrice; MockPricePicker(String c, long p) { itemCode = c; testPrice = p; } long getPrice(String c) { if (itemCode.equals(c)) { return testPrice; } return -1; // アサートされる数 } } public void testPick() throws Exception { fpp.setPricePicker(new MockPricePicker("ABCDEFG", 12345L)); long p = fpp.getPrice("ABCDEFG"); assertEquals(12345L, p); } public static void main(String[] args) { junit.textui.TestRunner.run(new TestSuite(FishPricePickerTest.class)); }
っていうか、ここでPricePicker
がクラスではなく、インターフェイスにしておくべき理由がわかる。もしPricePicker
がコンストラクタでいきなりJNDIからデータソースをルックアップする作りだったらどうよ? いきなり動かないわけだ。いやもちろん、テスト用のデータベースサーバといつでも接続可能なように開発マシンをセットアップしておいて、データベースサーバ(テスト用なんだけど開発中は上げたり下げたりしないようにして、って既に問題あるだろ)にはいつでも参照すべきテーブルを用意しておけば良いのだが、その場合はその場合で、テストケースの実行の都度コネクションをしなおすのはあほくさいぞ。コネクションプールが使えるわけじゃないし。だから、こういったクラスは実装クラスとその派生とはせずに、インターフェイスを常にきっておくべきなのだ。たとえば
public interface PricePicker { long getPrice(String itemCode); }
これだけのことだ。で、今までスーパークラスとして扱ってたやつはpublic class PricePickerImpl implements PricePicker
とすればいいだけの話である。当然、public class FishPricePicker implements PricePicker
とかprivate class MockPricePicker implements PricePicker
に変わるわけで、これでPricePicker
の実装を気にせずどこでも呼び出しが可能となるわけであるのである。というわけでたかだか(Javadocとか含めなければ)3行の1つのファイルを作る手間を惜しんじゃいけない。でも、まあ、ここではこのまま進めることにするけど。
というわけでPricePicker
をデコレート間接的に利用するようにFishPricePicker
を修正したから、これでテストプログラムを使って実行できるようになりました。めでたし。でも、そうじゃない。18:00以降の問題が残っている。本当に5割引きするのか、というか、仮に正しく作られていたらFishPricePickerTest
を18:00以降に実行するとアサーションに引っ掛かるじゃん。まずいじゃん。
何がまずいかというと、Calendar.getInstnace()
がまずい。実行環境の時刻に依存してるからだ。というわけで、ここを変形する。元のページだと一工夫あるけど、疲れてきたからストレートにやってしまう。
public class FishPricePicker extends PricePicker { Calendar calendar; PricePicker innerPicker; public FishPricePicker() { } public void setPricePicker(PricePicker newInnerPickder) { innerPicker = newInnerPickder; } public void setCalendar(Calendar newCalendar) { calendar = newCalendar; } public long getPrice(String itemCode) { assert calednar != null; assert innerPicker != null; long price = innerPicker.getPrice(itemCode); if (calendar.get(Calendar.HOUR_OF_DAY) >= 18) { price /= 2; } return price; } }
テストプログラムは次のようになる。
public class FishPricePickerTest extends TestCase { FishPricePicker fpp; protected void setUp() throws Exception { fpp = new FishPricePicker(); } private class MockPricePicker extends PricePicker { String itemCode; long testPrice; MockPricePicker(String c, long p) { itemCode = c; testPrice = p; } long getPrice(String c) { if (itemCode.equals(c)) { return testPrice; } return -1; // アサートされる数 } } public void testPick() throws Exception { fpp.setPricePicker(new MockPricePicker("ABCDEFG", 12345L)); fpp.setCalendar(new GregorianCalendar(2005,0,1,10,0)); // 日付は何でも良いはずだ。時刻のみ重要 long p = fpp.getPrice("ABCDEFG"); assertEquals(12345L, p); } public void testPickAfter1800() throws Exception { fpp.setPricePicker(new MockPricePicker("ABCDEFG", 12345L)); fpp.setCalendar(new GregorianCalendar(2005,0,1,18,0)); long p = fpp.getPrice("ABCDEFG"); assertEquals(12345L / 2, p); } public void testNoNoMatch() throws Exception { fpp.setPricePicker(new MockPricePicker("ABCDEFG", 12345L)); fpp.setCalendar(new GregorianCalendar(2005,0,1,10,0)); long p = fpp.getPrice("ABCDEFGH"); // マッチしない場合のルールが負値の返送で良いとは思えないけど。 assertEquals(-1, p); } public static void main(String[] args) { junit.textui.TestRunner.run(new TestSuite(FishPricePickerTest.class)); }
で、DIコンテナが必須かと聞かれるとその答えはNOということになるんですな。たとえば、次のようなファサードを用意するだけでも良いからだ。って言うか、extends
で良いかどうか、それをファサードと呼んで良いか、デコレータではないかとかいろいろあるが、実装はデコレータパターンを使った意味はファサードなクラスなのだ(追記:なんか本当にファサードかなぁという気もしてきたが、内部の事情を見せずに利用させてやるってことを考えるとやっぱりファサードであってるようにも思えるし)。
public class FishPricePickerFacade extends FishPricePicker { public FishPricePickerFacade() { setPricePicker(new PricePicker()); setCalendar(Calendar.getInstance()); } }
もちろん、FishPricePickerFacade
をTDDしたいという人がいても良いけど、さすがに、僕はこれには不要だと思うな。でも、そういう場合には、こういうある意味においては余分なクラスを作らないですませる方法がある。つまりDIコンテナを使うという方法だ。
注:当然だがある時点のCalendar
のインスタンスを使う格好で書いてあるわけで、これはもちろんまずい。元のページは時刻(じゃなくて月日だけど)を取得するインターフェイスを別に用意することで解決しているので、それについてはそちらを参照するか、正しく動作する方法を考えるべきでしょう。
ブラボーブラバーブラベスト。今まで見た中でもっとも素晴らしいDIについての知見(そう言えば矢野徹片手に灰になるまでやりましたな。忘れてたけど)。
CellEditorって、TableModel#setValueAtするとリセットされてしまうものだ(y/n)。
ジェズイットを見習え |
Before...
_ るいも [私のようにCtrlとCapsを入れ替えている場合は、使い物にならず、東プレに走ってしまいましたが、普通の配置で使う分..]
_ arton [それは嬉しい。よろしくお願いします。(ちょっと遅れ……というのは微妙ですね)]
_ 通りすがり [話題を始めたものです。モノによりいろいろ違いがあるようですね。 リンク先は、とりあえず目についたもので、 よく調べな..]