b;</code></pre>}という具合だ。この時点で、「非常に魔術的」な香りが漂っている。戻り値が参照出来るだとか、そもそも事後条件が除算処理の手前にあったりして、本当にこれでいいのか?という感じがする。実は、最初にインターフェイスが準備されただけ、と書いたのはこの部分の事で、このコントラクト定義を実際に使うには以下の条件を満たす必要がある。・コンパイル時シンボル「CONTRACTS_FULL」が定義されていないと、Contractクラスのメソッド呼び出しは全て削除され、バイナリには一切含まれない。・コントラクトの検証は、能動的には行われない。ように、書いた場所で直にコードが確認するわけではない。実際には一部の評価は行われるが、結局のところは「バイナリリライター」と呼ばれるライブラリが介在する必要がある。比べて何が嬉しいのか?という話になるのだが(ようやく本題)、コードに書かれたコントラクトをメタデータ(とMSIL?)から抽出して、その情報を元にごにょごにょ出来るようになるというところが違う。Microsoftの実装では、「Pex」というプロジェクトでコントラクトを利用している。Pexは、ユニットテストコードを自動的に生成するツールとライブラリで、コードからコントラクト定義を抽出して、事前・事後条件などからユニットテストが実行すべきテストパターンを計算、「テストコード」を吐く。恐ろしいwwいや、もちろん、完全な自動化テストは不可能ということは分かっているのだが、特にこの場合はどれだけコントラクト定義が綿密に書けるかということと、いかに普段からテスト可能コードを書けるかと言う事に尽きるのだが、それにしてもとうとうやっちまったかという感じがする。PexはVS2010のProfessional以上で使用可能で、MSDNサブスクライバダウンロードから入手可能。Ultimateでは標準で入っているので、Microsoftとしてももはやこのプロジェクトは実験段階を超えていると判断しているようだ。詳しく知りたい場合は、以下のサイトを参照されたし。Pex他にも、コントラクト定義を使ったこんなのもある。未満の互換ライブラリを書いているのであれば、ここにある前身バージョンを使えば、コンパイルは通るようになります。既存のドライバをビルドしてみたかったのだが、そのままでは出来ない。拡張アセンブリと思わしきファイルや、VSの拡張ファイルなどがある。OSRでもその手の話題が出始めている(真面目に見てないのでわからないが)。問題は、ドキュメントが無い事だ。料理していいのかわからない。Previewだからこんなもんか。気になるのは、2000はアウトとして、XPはどうだろう?というところかな。2000はすでにWDK6001で終わってしまっている。今は仕方がないので、2000向けだけ6001で、あとは7000でビルドしている。この方法は、良くも悪くもbuild.exeがあるから使えるわけだが、build.exeが綺麗さっぱりなくなるのであれば、いよいよ2000のフェードアウトを考えなければならないか...うーん、1ビルド分は、build.exeシミュレータみたいなものを用意して欲しかった。8(仮称)が発表され、MSDNサブスクライバダウンロードからプレビュー版をダウンロードできるようだ。8でMetroインターフェイスが導入されるのだが、心配している点がある。「プログラムマネージャ」と「ファイルマネージャ」が導入された。この時に「なんてダサいインターフェイスだ」と思った。DOS世代のアプリケーションランチャーとファイラーをそのまま実装しただけだった。Finderの足元にも及ばなかった。「これが未来か!」という気は全くしなかったものだ。なんという名前だったか忘れたが、Finderもどきのユーティリティがあったりしたが結局純正ではなかったので、広まることもなかった(詰めも甘かった)。DOS5で導入された「DOSシェル」も、結局は薄皮かぶったドブネズミ状態だったわけで、もっと根本からリソースを共有するための、優れた手段を提供しなけれなならないのにと思っていた。UNIXはその点では優れていたが、現代のUNIXクローンもまたそこから脱することは出来なかった。#未だにshとcshの延長でしかないし。#その世界で完結する作業をしている分にはすばらしいが、#多様化するユーザーインターフェイスを一元的に扱う機能は提供されていない。#シェルの強みはパイプラインとジョブコントロールだと思っているので、#それを超える操作は、独自ライブラリ・独自APIの世界にならざるを得ず、#突然相互運用性と応用性を失う。私がどうもAndroidにもiOSにも萌えないのは、あのメニューがプログラムマネージャに「クリソツ」だからかもしれない。95で「エクスプローラ」が導入された。ファイルセントリックで、コンテキストメニューで操作を提示できる点は進んだと思う。「デスクトップ」と「マイドキュメント」の概念がダメダメだ。ツリーでディスクとフォルダ構成を見せている以上、内部の構造がそのまま素直に見えるようにすべきだったと思う。あれがひっくり返っている(デスクトップがすべての起点にある)のが諸悪の原因だ。技術者ではないユーザーは、あれのためにコンピューターの中のイメージが持てなくなってしまった。何回こういう説明をしただろうか...未だに、マイドキュメントの位置をDドライブに移動するという説明を理解してもらえないことが多い。(メーカー製のPCはせっかくパーティションがわけてあっても殆ど無意味なのだ)ユーザーの学習曲線について考える責任者がいなかったのだろうか、或いは分かっていてやっているのか。デジタルディバイドという言葉があまりはやらなくなったが、「デジタル音痴」はいまだ多数を占める。いう層の人ほど、コンピューターの応用方法を早く習得できる必要があるのだ。そのためには、ただでさえ分かりにくい「コンピューター」を、更に理解不能にする要素は排除する必要がある。UNIXのシェルは多少ロジカルな思考が必要だが、一度理解すれば応用力はどんどん伸びていく。Windows環境ではこういう経験はほとんどない。環境どころかAPIも一貫性が無いおかげで苦労する。GUIの世界が一般的になった時、UNIXクローンも同じような問題を抱えるようになった。(向こうはもっと激しいよね。7.5のMetroインターフェイスには少し期待している。「一から作った」ということは、過去のWindowsの文化を全て捨てて考えることが出来たと言う事だ。Labs内で終わるようなプロジェクトにゴーサインが出たわけだ。Peopleハブは正に、「Peopleセントリック」ということだろう。新しいデバイスであるからこそ、既存のデバイスを打ち破る「文化」が無いと魅力を感じられない。進化が無いなら、今までの環境で十分。新しいデバイスに投資するなら、それだけの価値がないとね。(価値は個人によるので、他人はどう感じるかは別の問題。Phoneという小さいデバイスであまり夢を見ることもできないが、いっそ「メタセントリック」を扱えるように出来れば、OSの応用性に未来が見い出せるのではないかと思う。Windowsのメインプロダクトが目指してほしいところはここだ。Windowsのメインプロダクトは過去を捨てることが出来ない宿命にある。Metroインターフェイスを導入すると言っても、それはつまりは「新しいプログラムマネージャ」ではないかという気がする。Frameworkは良くできていると思う。周りからの色々な圧力(?)に屈せず、よくあそこまでの完成度にたどり着いた。Frameworkで再構築するという大胆な案は、もう実現しそうにない。夢は見れたかもしれないが、やはりそれだけでは「商売」にならないということだろう。それはつまり、まだしばらくはWin32とWDMからは逃れられないと言う事だ。なると、新しい機能はすべからく「ラップインターフェイス」となる。8のMetroが、「羊の皮をかぶったドブネズミ」でなければいいのだが。7.5で「儲ける」のはまだ先かな。今のうちにかじっておくと幸せになれるかもしれない。アイデアがあれば!#シェルと言えば、PowerShellを必要に迫られて多少弄ったが、どうしても「できそこない」感がぬぐえない...#パイプラインが、テキストストリームから卒業した点は評価している。Frameworkがもっと早く完成していて、同時にPowerShellがリリースされ、#標準のシェルがPSになっていれば、もうちょっと印象がちがっていたかもしれない。#でも、シェルコマンドのライブラリ作成がスマートじゃない。なんか異端な感じがするんだよな。#よく頑張ったとは思うけどね。#そういう印象は、Exchangeのコマンドレットを見ると特に強く感じる。#PS使います・コマンドレットです、って言うだけで、応用性無いじゃん。#あんな大量のコマンドレット、専門職じゃないし使えないって。VPCZ21AJ」うーん。そもそも高速GPU欲しい人が、「分離した」ノートを欲しいと思うだろうか。Expressのブリッジが実現できたとか、技術的なチャレンジとしては#面白いかもしれないけど。「分離できます」よりも「内蔵できませんでした」#に思えてしまう。前回までの内容で、COMが裏で何をしているのか、少し見えたような気がすると思う。ここで重要な「嘘」を公表しなければならない(大げさか)。今まで、ファサードが存在する理由としてスレッド同期を挙げたのだが、そのこと自体は間違っていないのだが、同期の対象が違っていた。コンポーネントの「単一のインスタンス」について同期を行うために、ファサードを挿入すべきか否かという話だったのだが、実はそうではない。本当のCOMでは、同期の対象は「ウインドウ」である(ほぼ)。APIの生の呼び出しで、一からウインドウを生成するコードを書いたことがあれば、これは自明である。ウインドウにまつわるAPIの大半は、対象とするスレッドを限定する。C++で、新しくWin32のプロジェクトを開始してみてほしい。APIの直接呼出しの、懐かしい、目を背けたくなるコードだ。そのコードには、CreateThreadや、beginthreadexのような、スレッド生成のAPI呼び出しは存在しない。このコードは「シングルスレッド」で実現されている。実行すると、単一の味気ないウインドウが表示される。一通りの操作が可能である。ウインドウが生成されると、「ウインドウハンドル」が返される。ウインドウハンドルの値は不透明値なのだが、user32ライブラリ内で非公開の構造体を指しており、この構造体はウインドウを生成したスレッドと結びついている(スレッドハンドルを保持しているのか、スレッドローカルストレージに関連付いているのか、詳細はわからない)。ウインドウメッセージは、例のメッセージ転送ループ(GetMessage→DispatchMessage)によって、これらのウインドウに転送されるのだが、このループはウインドウが関連付けられているスレッドで実行される(というよりも実行するようにコードを書く)。プロジェクトテンプレートでは単一のメインスレッドを使うので、これらが全て同じスレッドで実行されるわけだ。ウインドウにボタンがあったとして、ボタンクリックに反応するコードを書いたとしよう。「シングルスレッド」なので、ボタンクリックの処理中に別のメッセージが発生することはない。DispatchMessageからウインドウプロシージャが呼び出され、ボタンクリックのお手製コードが走っている。そのため、この処理が終わって、次にGetMessageが呼び出されるまでは、新しいメッセージが目に見える形では現れない。したがって、マルチスレッド実行による、複数のメッセージの同時発生と実行を考慮する必要はないわけだ。APIが設計されているともいえる。この制限が時には苦痛となる。時間がかかる処理を行う場合だ。そのような処理をボタンクリックの処理で実装すると、ウインドウは他の処理が実行出来ない。ウインドウのサイズ変更・移動・ウインドウの描画まで含めて、「固まった」かのようになる。仕方がないので、ここでワーカースレッドを生成して、長く時間のかかる処理を委譲したとする。これで、長い処理を並行して実行できるので、ウインドウの基本的な動作に支障は出なくなる(ボタンが2回クリックされないように無効化するなどの工夫は必要だが)。このワーカースレッドの処理が完了したときに、それをどのようにウインドウに通知するかと考えた時に問題が発生する。大半のウインドウAPIが、特定のスレッド(この場合はウインドウを生成したのがメインスレッドなので、メインスレッド)から呼び出されないと機能しない、あるいは誤動作を起こす。そこで、PostThreadMessageなどを使って、メッセージキューに結果となるメッセージを送信する。メッセージキューはそのうちメインスレッドのGetMessageによって引き出され、晴れて「メインスレッド」でメッセージが処理される。この特別なメッセージの処理コードを書いておけば、ワーカースレッドの処理結果は間接的にメインスレッドの実行中に処理され、ウインドウに何らかの表示を行ったりすることが出来るようになる。Frameworkにおいても、System.Windows.Forms.Control.Invoke()などを使って、背景では同じことを行う。乱暴な言い方をすれば、クリティカルセクションがウインドウに紐付いていて、ウインドウを基準に同期を行っていることに等しい。分かっている人には当たり前のことではあるが、この制限をスレッド親和性のモデルとしたのが、COMのアパートメントというスレッド属性だ。それはCOMの構造を設計したときに、それがスレッディングにまつわるWindows独自の問題だったからだ(多分)。何らかのアプリケーションのソースコードが手元にあったとする。このソースコードはすでに規模が大きく、マルチスレッドに対してどこまで安全であるかが分からない。注意深く設計されていれば、スレッドの導入にも頑健であるだろうが、今までにファサード導入で見てきたように、スレッド親和性を担保するには相応のコストが必要だ。おまけに、ウインドウの制御に関しても、どのウインドウがどのスレッドに紐付いていて、どう安全でどう危険であるかも明らかではない。アプリケーションによっては、GetMessageとDispatchMessageによるメッセージループが「複数」の別々のスレッドで実行されている可能性すらある。同じ問題が(一般的なCOMではない)コンポーネントライブラリにも存在する。このような状況下では、あるコンポーネントがあるアプリケーションやコンポーネントと協調して動作させるなど、効率以前の問題で、悪夢としか言いようがない。サードパーティ製のライブラリを結合するとき、スレッド親和性についてほとんどの場合は無視(つまり親和性などなく、ウインドウとスレッドの安全は自分で担保が必要と仮定)するはずだ。COMは「インターフェイス境界」が非常にはっきりしている。そのため、この境界を基準として、ウインドウに紐付いた暗黙のスレッドとの競合についても、背後で面倒を見ようとしたわけだ。Fifteen.%d人のブロガーが「いいね」をつけました。