家に帰って寝てしまう。いつも寝るの遅いかな。
学校いって寝ると何もしていない気がする。実際かなりの時間寝てたみたい。っていうかほんとに何もしてないね。メール見て、メール書いて、ネットまわって、日記を書く。書こうにもネタがない気がするんですけど。
ネタがないときはためといたネタを。今日はブラウザ対決の話。大体ウェブブラウザといえばIEが多いと思う。その他のブラウザといってもWindows用だと結局IE使ってるのが多いし。特に日本のフリーウェアなんてIE使ってるよね。ほかにもMSNやNeoPlanetもIEだし*1。MacでもIEは優勢だね。
さて、IE以外のブラウザといえばNetscapeが有名どころ。NN4.xといえばNetscape Navigator4.〜というわけ。確かに悪いものじゃないんだけど、今じゃちょっと古い。サイトによっては正常に見れないとこも出てきてるはず。その新しいのは今はNetscape6.2かな。ちょっと重いながらもW3C標準のほとんどをカバーしているし、スキン機能なんかもあるから結構面白いと思う。とはいっても結局実装はMozillaなんだけど。これはNetscapeのオープンソースプロジェクトで、新しいブラウザをオープンソースで作るっていうんだけど、当然Netscapeよりリリース速度は速い。どんどん新しい機能が盛り込まれて便利になっている。バグもすぐ直っていく。英語を読むのがそれほど苦にならないならこちらを使うべきかもね。あとはWindowsだけでなくMacOS、BeOS、UNIX系の多くのOSで動くのも利点。Windows以外では使えないブラウザ用にページ作るのも馬鹿らしいわな。
ほかにもある。Operaとか。シェアウェアなんだけどかなりいい線いっていると思う。CSS2.0にも対応しているし、JavaScriptも大体動く。日本語のページも6.0から読めるようになったから、これで使え度が格段にアップした。注目のブラウザだね。JavaScriptは6.0betaの時点ではまだ甘いところもあるみたい。でもCSSの表示についてはWindowsのIE6.0より上。意図したとおりに表示してくれた。日本語版が出る可能性もあるようなので今後に期待かな。こちらも対応プラットフォームは多い。ただし、各プラットフォームでバージョンにかなりばらつきがある模様。
あと、はずせないのはMac版のIE。これはWindowsのIEより数倍良い。なにやってるんだMicrosoftって感じですね。最新のIEはCSS2.0に世界初完全対応とかいう話を聞いた。WinのIEはMozillaやOperaに追いついてもないのに、Mac版はそれを追い越したみたい。Mac版ではPNGのアルファチャンネルに、先進的なブラウザらしく当然の様に対応してるんだけどWin版はいまだに対応していない。そういえばOfficeもMac版のほうがいいみたい。開発者自らが「他のプラットフォームのOfficeより良い」と言ったらしいからね。他のプラットフォームといえばWinしかないわけだが(笑)。
Windows版のIEは、はっきりいって変なブラウザである。NNとの独自機能の追加合戦があったわけだが、その名残はまだ消せていない。しかも、6.0で標準に準拠しようと中途半端にがんばってみたため、いままでIEで表示できたページが正常に表示できなくなったらしい。まあ、そんなページ作るほうが悪いんだが。しかし、準拠の仕方が中途半端だ。CSS2もろくに表示できていないくせに、CSS3のドラフトの一部を取り込んでみたりとかする。PNGのアルファチャンネルも扱えてないくせに、CSSのアルファは使えたりする。セキュリティ対策としてcookieの制限をつけてみて、コンピュータ初心者にわかりづらいような設定をつけてみる。標準でcookieを受け付けなかったりとか。標準に準拠するといいつつ、標準をつまみ食いしてるとしか思えない。これはブラウザというよりOSの一部だから、OSの機能を上げるのに精一杯で、標準に準拠してるひまはないのかな。
他にもブラウザはあると思うが、今日はこの辺で。
そういえばIME2000。陰陽師(おんみょうじ)の変換も出来ない。こういう使えないソフトばっかりだから批判されるんだろうな。派手な(無駄な)機能ばっかりつけないで、ユーザーを意識して使いやすいソフトを作ってくれたほうがいいのに。結局、企業向けに使えない高い製品売り付けてた方が儲かるんでしょうね。
明日までのレポートも適当に終了。
Ridgeの実装をもう一回考え直す。昨日はメッセージループをうまくすれば大丈夫みたいなことを書いたが、それじゃやっぱりだめなことに気づく。あうー、考えの方がループしてるよ。やりたい事をまとめてみよう。
SimpleWindow::new.run.join
というコードがまともに動くようにする。ただ、これだけなら簡単なんだけど、次のようなときに大変。
win1 = SimpleWindow::new win2 = SimpleWindow::new thread1 = win1.run thread2 = win2.run ...
このときには、たくさん問題が出てくる。まず、スレッド終了の問題。スレッドがいつ終わるかである。thread1のwin1が閉じたときにWM_QUITをPostするとthread2まで終わってしまう可能性がある。最悪thread2だけ終わる。これは、スレッド中のトップレベルのウィンドウの状態を調べるだけでいいかもしれない。つまり、thread1はwin1が今閉じてるかどうかで、終わるかどうかを判断する。
もっと困るのが次。GetMessageによるブロックの問題。WinAPIのGetMessageを呼ぶと何かしらメッセージが届くまで、Sleepしていることになる。Rubyのスレッドは擬似スレッドみたいなものだから、OS側からみればRubyはシングルスレッドで走っていることになる。GetMessageでシステム的にSleepすると、実質的にRubyのプロセスがSleepしたことになる。つまり、thread1でGetMessageを呼ぶと、メッセージが届くまで、ほかのスレッドも一緒にとまってることになる。上の例だと、どうせ他のスレッドもメッセージ取ってるだけなんで関係ないかもしれないが、たとえばdRubyとかと一緒に使うことを考えると破綻する。Rubyの簡単で便利なスレッド機能をすべて捨てるのに近い状態だ。
ここででてくるのがPeekMessageを使えばいいという案。しかし、PeekMessageを使ってると、メッセージがない間Sleepされることによってメッセージループに無駄なCPU時間を割り当てなくしている意味がなくなる。つまり、1プロセスが無駄なループに100%CPUを使ってしまう。適当にSleepを入れてもいいが、CPU時間の無駄遣いはちょっと抑えられ、Ruby自体の動作も、少し遅くなりはしても普通に動くだろう。だが、その方法で動くスレッドが10本同時に動いたらどうなるだろう。Sleep(100)が入っているスレッドが10本。一周するのに、最低1秒かかることになる。dRubyのスレッドが走っていたら、クライアントからの要求がきてから処理を起こすのに1秒以上かかることがあるというわけだ。一回の通信でそれだから、実際の運用には大変なことになる。5人同時につないでたらクライアントは、1回の処理に5秒以上待たされる事だってありえる。そこまでシビアなことはしないだろうけど。問題は、この数字が端末の処理速度に依存しないって事だ。ちょっと遅いんです…ってぐらいなら、時間が解決してくれる。1年後には有名メーカー製パソコンの搭載CPUのクロックがざらに2G超えてたっておかしくない時代だし。しかし、この方法では10本動かすと、必ず1秒は寝ている。寝すぎだよ。
それで解決法として提案するのが、メッセージループを「本当に別なスレッド」へ追いやってしまう方法。Rubyのスレッドじゃなくてシステムのスレッドを使えばいいのだ。これなら、メッセージループがGetMessageでいつまで寝てようが、Rubyのスレッドとは関係なく寝てるだけなので、Rubyは動いていられる。この方法だと、別スレッドからRubyのコードを実行するのに、Rubyと同期を取らないと危なくて仕方がない。そこはそれ、工夫のしどころ。Ruby側にはRubyのスレッドで、同期用のスレッドを立てておく。別スレッドからRubyのコードを実行することがあれば同期用のスレッドで実行をとめ、それからコードを実行する。終わったら同期用のスレッドのブロックを解除し、いつもどおりに流す。これでうまく通るはずだ。
そこで問題になるのが、システムのGUI関係とスレッド。WindowsだとhWndを引数に取るAPIは大抵同じスレッドからじゃないと呼び出せない。つまり、ウィンドウ等の操作にAPIを使えることがほとんどないわけだ。ほとんどの場合、PostMessageを使ってメッセージを送るだけになる。SendMessageも期待できない。というか、デッドロックの危険があるので使えない。←これはWindowsのマルチスレッドのお約束みたいなものですね。Rubyで組むときにはまったく気にならないんだろうけど、ライブラリ(Ridgeやその拡張)を作るときは常にマルチスレッドを気にかけなきゃならないのも痛い。自分は別にスレッド好き(?!)だからいいんだけど、だれかがクラス追加したいとか思ったときには大変でしょうね。
素直に次のような仕様にはならないのかという話もしておく。こんな仕様。
app = Application::new win = SimpleWindow::new app.add win win.show app.run
app.runはスレッド返しもせず、そこで動作をブロックするというもの。あとwinでメッセージ受け取ったら、指定された動作をするだけってやつ。いまあるRubyのGUIライブラリって大体こんなもんでしょう。すくなくともApolloとRuby/Tkはこうなってますね。Windows用のクラスライブラリもこんな感じかな。
つーことは、結構一般的な仕様なんですが。この仕様には違和感を感じます。app.runがね。よくわからないけど、そこで実行を止めてるわけです。我が物顔で。いかにも「GUIアプリケーションなんだぜ」と威張ってるみたいですね*2。これは許せません。アプリケーションが終わると無常にも消されてしまうウィンドウがいいんだと思いませんか。威張って実行をとめたりしないで、メインの流れが終わったらウィンドウは一瞬しか出てないにもかかわらず消されてしまう*3。ああ無常(笑)。
ここまで書いてちょっと思ったのが、app.runとか書いてブロックされた瞬間に、スクリプトの流れが奪われて、まったく別な場所で流れができることが許せないんでしょうね。明示的にjoinとかすると、ここでそっちのスレッドに流れを任せたんだなってのがコードを見てわかります。見てわかるコードになることが、わかりやすいライブラリだと思ってるんですが。
Ridgeの目標、第二段
あう、大変だ。ああ、面白い。
特許庁は大変だと思う(いみふめい)
Pascalが。Pascalがわからんのだよ。Delphiのことね。動的配列で1時間以上悩まされた。なんで、array of IntegerのCopyがarray of Integerの変数に入らないの?型の互換性がありませんってねぇ。と思ってみると、Copy元にそのまま代入しようとすると入るし。片方がグローバル、片方がローカルって関係ないよね、きっと。結局静的配列でとってループでコピー。ポインタなんて物は基本的に使わないよん。C++でもね*4。やっぱ、JavaとかC++の方がよかったんだろうか。いまさら仕方ないが。
結局情報処理の試験は本を買う。ああ、無駄な出費。買うときには例の商品券は使えず。使いどころがない…。
無茶な回路を組まされる。回路図が間違ってるのは少しだからまだいいとして、部品は間違ってるし部品がでかすぎる割に基板は小さい。図通りに組むと、部品と部品が重なります。置けるわけないじゃん。しかもこれを改良せよと?時間も部品も*6ないのに。授業でもなく楽しくもなく、こちらに何らメリットがないのに半強制でやらせておいて、何が物作りだっていうの。うちでプログラム書いてた方がよっぽど物作りです。そんな強制的な考えしか出来ないから学校が嫌になるのよ。いや、学校というかつまらない授業が嫌ですね。学校はいってるし、授業もまじめに受けてますが。まあ、進学進められても無理だね。もう学校に行く気はない。何ならもうやめたいぐらいに。しかし、一番楽しいであろう卒研を逃しては学校を辞めることは出来ません。何のためにここまできたんだか。
まあ、もの作りって言うのは簡単ですが。物を作れば何でも楽しいわけじゃないんですよね。それで楽しいんだったら、体動かしてりゃなんでもいいみたいで。スポーツだって一定の、うまく練られたルールの元で以下にベストを尽くすかってのが楽しいんだし、キット渡されて「つくれよ」っていわれてもねぇ。レースやって商品が出る。汚い手段ですね、物で釣ろうとするの。それだったら自分たちでルールを決めて、商品も限られた範囲で用意して、それなりの時間を取ってやるようにすれば少しはやる気もでるでしょうに。結局来年度からの1年生のための実験台にさせられてるだけなんでしょう。作ってるところの写真とられて、作ったものは学祭の見世物にする気してるらしいし。みんな競っていいもの作ると思ってるんでしょうか。実際はみんな仲良く、この無駄な時間を乗り切るかでいっぱいなんですけど。楽しんでる人は少ないよ。
と、まあ最近こんな感じ(笑)。簡単な回路なんでささっと終わらせるのが筋なんでしょうが。Delphiといいこの回路といい、今日はろくなものにぶち当たらなかったなぁ。あ、B-Fileにあたったか。
最近おもったこと。コンパイラが意味不明なエラーを出すこと以上に腹が立つことはない。さらにそのエラーのヘルプを見てもわけがわからないと余計には腹が立つ。
ついでに。VCLに文句あるとすれば柔軟さかな。TMenuから継承して、TMenuItemから継承した物を使うメニューが作りたかったんだけど。TMenuItemの作成がハードコーティングされている。変更のしようがない。つまり、あとから自分の手でAddItemとかつかってちまちまとメニュー作れっていうのかな。その問題はあきらめたからもういいけど。スレッドセーフでないっていうのは、知ってたからそんなに文句は言えないけど。ひとつ言うならグローバル変数使いすぎ。気合入れて作られたライブラリっていうのはよくわかるけど、もうひとついまいちな部分が見られる。この辺は好みにもよるだろうな。Borlandはいま一度VCLを捨て去って、まったく新しいクラスライブラリを作るとなれば、かなりいいものが出来ると思う。売れてるからつくらんと思うけどね。
簡単と使えるっていうのの両立は非常に難しいってのが実感されてきた。とくにRidge作り始めてから。VBは簡単に見えるかもしれないけど、その実役立たず。Automationコントローラには使えるか。Delphiはそれだけで何かしようとするといいんだけど、凝ったことやるには荷が重い。結局API使って、低レベルなライブラリ(WTLとか)つかってが楽になってしまう。慣れてくるとね。隠す部分と見せる部分の問題って事ですね。うーん、RidgeもVCLと同じ感じになるのかな。目指すところはRubyにおけるWTLみたいな物なんだけど。「必要十分」。もっとも難しいと思うテーマ。Ridgeはこれを目指そうと思う。
なんてな。結局Ridgeはスレッドで分けることは断念。というよりは、メッセージループを工夫すりゃいい事に気づいた。まだ実装はしていないけど。Windowsで無理するのはよくないね。BeにはBeなりの、WinにはWinなりのやり方があるんだし。
ああ、疲れた。わけのわからない文章書いてしまった。ということでまた明日。
今日はWin上から。
情報処理技術者試験を受けようと思ったんだけど。願書が手に入らない。学校は当てにならない。インターネット上からの受付は本人名義のクレジットカードのみ。なんで?クレジットカード持ってないんですけど。取り寄せると送料200円がかかる上に一週間程度かかるらしい。何でそんなに時間かかるのよ。うまくいって着くの締め切る直前じゃん。というわけで、願書付の本を買いに行く。え、千円もするの。いや、べつにシスアドとか基本情報処理とかは付いてなくていいから、もっと薄くて安くていいのに。まあそれでもうけてるんでしょうけど。
そういえばCASL2エミュレータなんてものがあったのね。べつにエミュレータ使うほど複雑な機能もってないと思うけど。問題も簡単だし。あれだけじゃアセンブリっていうにはちょっと弱い気がするけど。Cと比べたらこっち取るわな。だってCは問題ややこしいけど、アセンブリはとても簡単。この差はいったい何なんでしょうね。
Ridgeの続き。こんなコードが書けるようになった。
SimpleWindow::new.run.join
これだけ。これで動きます*7。のっぺらなウィンドウが出てきて、閉じると終了します。newでウィンドウのオブジェクト作って、runで表示・(Rubyの)スレッド作る・スレッド返す、joinでスレッドが終了するのを待つ、てな感じ。スレッドは当然メッセージループ。ウィンドウが全部閉じると抜けます。
と、そこまではいいのだけど。runがたくさん呼ばれたりするとまずい。Rubyのスレッドはインチキな*8スレッドだから、メッセージループが混ざる。システムのスレッドならそんなことはないんだけれど、そっちからRubyのスクリプト呼ばれるとまずい。いちいちメインのスレッドと同期取るためのRubyスレッドが必要だ。しかも面倒なRubyスレッド。グローバルに読み出せるようなやつね。うあ、やだな。一般的なGUIライブラリにApplicationがあるのがよくわかる。ん。なにもメインスレッド側の同期取るRubyスレッドはひとつでなくともいいのか。なら出来そうかも。どうせBeOSでは一ウィンドウ一スレッドなんだから、Windowsでも似た感じにすればあとで楽かな。しかし実装はめちゃくちゃ面倒になるな。ま、いいか。スレッド関係ぐちゃぐちゃにするの好きだし(笑)*9。
おっと、M with DeskBandのリリースをしなきゃいけない。忘れるとこだった。
今日はBe上から。
ついにBe上から書くことに成功。簡単だったんだけど。MuTerm上で「vim -T be_ansi」だけ。MuTerm上じゃbeのTerminal扱いしてくれないんだね。あとはマウスはxterm上かGUIのみらしいんで諦める。GUIのコードを書き換えるしか無いのか。あとは環境を地道に整えるだけ。わーい。
スキャナを売ってくる。あとPC版のVampire。スキャナはドライバのCD-ROMの端の方に傷があるとかで安く買い叩かれる。そんな端の方まで書き込まれてるような物無いだろうに。とは思ったものの、機種によっては読み込めない可能性がありますので、とか言われたら仕方ない。確かに可能性としてはあり得るからね。結局合計\1200。なんてことだ。一週間ぎりぎり持つぐらい?スキャナがまともな値段で売れればなぁ。ま、いざとなったらどうしようもない商品券を売るなりなんなりするか。
Be関係のサイト行けば何処の日記にも書いてあるけど。dano入れました。今日のスクリーンショットはdanoな感じ。日本語フォントは小さい表示だとへた字とかダメ字みたい。嫌いじゃ無いけど。アンチエイリアスがききまくり。小さいフォントにもかけると訳が分からなく。アンチエイリアスオプションにTVってあるんですけど。まさかTVだけで操作することはないよな。ん?そうかBe-IA用の機能なのかな。
Ridge*10をちょびっと進めてみる。取り合えずWindowを表示させただけ。しかもメッセージループ無しだから、ただ出ただけ。何処にループ入れようか。win.show中に入れるつもりだったけど。別にwin.runでもつくっておこうかな。それなら区別しやすいし。わざわざApplicationクラスを定義する気は無いしね。いつもそんな大規模なアプリケーション開発するわけじゃ無い。それにそれが目的のライブラリじゃ無い訳だから。
*1NeoPlanetはMozillaもつかえるね。
*2主観モード(笑)
*3win.runとかやって、スレッドにjoinするのを忘れたりとかしたとき。
*4スマートポインタ使うんで…。
*5いろんな意味で(笑)
*6ついでに金も
*7実際にはrequire "ridge"; include Ridge;が必要ですけど。
*8といったら難だが、プリエンティブなとかいったっけ?
*9よい子は真似しないでね。
*10Ruby用GUIライブラリ