ふと覗いた Blog に載ってた JavaScript コードに違和感を覚えただけの話。イベントに関数をフックするために onload プロパティを使っているのだが[1]、それが一風変わっていた。以下引用(強調筆者)。
<script> function minomonta(){ var spans = document.getElementsByTagName('span'); for (var i = 0, l = spans.length; i < l ; i++){ var span = spans[i]; if (span.className != 'monta') continue; span.setAttribute('title', 'ここをクリックすると...'); span['onclick'] = function(){ this.style.backgroundColor = "transparent" }; } } minomonta(); </script>
なぜか onclick プロパティの参照だけ、コードの他部とは記法を変えてある。span.onclick
と同じ意味。
一貫性を保つためにも、ここは span.onclick
の方が妥当なのではないかと思ったが、それともコードの著者はあえてイベントフック用のプロパティには span['onclick']
の記法を採用しているのだろうか。
以前 object.property
と object["property"]
が同じ意味なんだといったら驚かれたような記憶があるようなないような気がしたので何となく雑文を書いてみた。
余談だが、文字列によるプロパティ参照方法は、データ構造でメソッド起動の場合分けができるようになるので DOM Tetris 2 でもおおっぴらに使用していたりする。かなり便利。しかし同じメソッド名を2箇所に書かなければならない諸刃の剣。冗長かな、とは思っているのだが……。
addEventListener
などの、イベントリスナに add
するタイプのインタフェイスを使った方が汎用性も高いうえに removeEventListener
などでバインドを容易に解くことができる。とはいえ本文の話とはズレるので脚注扱い。今日も思い立って DOM Tetris 2(tetris.js
, prototype_plus.js
, tetris.css
( IE6 Only
))のコードをいじる。主にオブジェクトのインタフェイスいじり。つーか TetrisDOMElement
オブジェクトの改良。前よりマシになったんじゃないかとは思う。簡略化しただけだが。あとはそれにあわせて CSS のちょっとした修正。
いい加減、TetrisTimer
と TetrisScore
もまともな実装にせにゃならん。まだ TetrisMessage
は実装すらしてないし……。
そういえば継承構造をアスキーアートで書き、tetris.js
にドキュメントとして載せた。次のような感じ。
Array (配列オブジェクト) +- TetrisObject (基礎オブジェクト) +- TetrisEvent (イベントコントローラ) | +- Tetris (テトリスゲーム) +- TetrisBlock (ブロック) +- TetrisDOMElement (XHTML 要素と W3C DOM インタフェイスによる描画) +- TetrisElement (描画単位オブジェクト) +- TetrisTime (時間管理) +- TetrisScore (スコア管理) +- TetrisMessage (メッセージ管理) +- TetrisField (描画オブジェクト2次元配列) +- TetrisGameField (ゲーム領域) +- TetrisNextField (次ブロック領域)
大本を Array
にしておいて、TetrisField
が実装できるようにしてある。そもそも Array
自体が汎用性に優れたオブジェクト。継承しておいて損はない。使わなくても問題ないわけだし……。
明日でようやく一週間おわり。今週末は実家に帰省する予定。あんまり時間かからないし。1.5 から 2.0h ぐらい。この機会を利用して買いに買った本たちを全部読んでしまおう。ああそういえば今日もまた色々と買ったので一応列挙。お茶を濁して今日はおしまい。
TetrisTest
に TetrisEvent
を継承させる今日も継承バシバシ使うようになって色んな意味で調子にのりがちな DOM Tetris 2(tetris.js
/ prototype_plus.js
)いじり。言ってしまえば「支配者たる親玉がイベント管理もやらにゃならんのに、どうして別オブジェクトで持ってなきゃならんのだ馬鹿馬鹿しい」という具合。キー対イベント対応の連想配列は分離してある(全ての根源たる TetrisObject
の配下にある)ため、親玉(になる予定の)TetrisTest
にメソッドを追加してから連想配列もそれにあわせるだけでイベントの対象にしてくれるという按配。ちょっと手を加えるだけでできちゃったので、今かなりゴキゲンなのだ。でもまだ未完成なので改良はこれから。
DOM Tetris 2 では今のところキーイベントにしか反応させないので他のイベントは全部無視できる。そのためキーイベントを捉えることだけ考えればいい。
一番の問題になっているのは、擬似キーリピートの ON/OFF とインターバルが全部のキーで同一になっていること。これかなり問題ある仕様なのだ。
例えばポーズ(一時停止)を考えてみよう。Tetris に限らず、一般的なパズルタイプのゲームでは、考える時間を与えないようにわざとポーズ時にブロックの描画をぜんぶ消してしまったり、ポーズ画面で隠してしまったりする。しかし素早いキーリピートが可能なら、これはまったくの無意味になる。残像が残るぐらい素早く切り替えて、時間稼ぎができてしまうからだ。
よって、キーによってキーリピートの可・不可(つまり ON/OFF)を切り替えて、かつリピートインターバルも個別に設定できなければならない。かつ、キー押下の禁止時間も設定できた方がいい。これらの改良はちと面倒なのでこれからの課題。
明日も飲み会か……ここ最近連続すぎ。いやそりゃ営業族に比べりゃマシかもしれないけどさ、それでも週に一回のペースってナニよ。財布の中身がすっ飛ぶよ。自分で酒買って呑んだ方がおいしい酒が呑めるうえに安上がりだよ。店がすごくおいしい料理を出して、いい酒を出してくれるなら文句いわないんだけどね……。そういうところじゃないから。
ふはははは。何なんだ今月は。即購入ブツばかり出揃いやがって。これじゃあ金欠確定じゃないか。ちなみに今日の購入物は以下。
ついに出ましたよ『膚の下』文庫版。このときを待っていたのだ。結構厚いなぁ。本棚の神林ゾーンを見ても、ちょっと文庫でこれより厚いのは見当たらない。いや、まだ持ってない著作あるけどさ……それでも、ね。何気に下巻についてる解説の著者、笠井潔氏だったりする。本人が書きたがったか、編集部が狙ったか。両方のような気もするけど。
『S-F マガジン』は異色作家特集。まだ読んでないけど。ぼちぼち読みまっせ。『ジャン・ゴーレ』もあの大風呂敷どうするんだよという具合だが、不思議と何とかなっちまう――というか、何とかしちゃうと思われる。ぐーちょぐーちょ。
『ユリイカ』は米澤穂信特集。ぶっちゃけ名前知りませんでした。でも対談の相手と微妙に「おいおい」となる副題に着目。だって相手は笠井潔アンド滝本竜彦。おもしろくならないわけがない? と。ちなみに滝本氏との対談副題は『HTML 派宣言! ネットが僕らの揺藍だった』。……そこに X がつかないのがミソかも。もしくは ISO じゃなかったり。バージョンいくつなのかな。やっぱ 4.01 だよなぁ。当たり前に考えて。
『エマ』はもう説明もクソもないやな。私はとりたててメイドスキーなわけではないのだが、このマンガがもつ空気感がすごく好きだったりする。『蟲師』とよく似てる部分がたくさんあるとも思ってる。
『キミキス』は、完全に作者買い。そして大当たり。いろんな場所でも騒がれてるが、それも至極当然なのかも。……だってエロいんだもの。「寸止めの美学」をこれでもかと自然に投入し、かつあざとさも残しつつ、ああもう摩央姉ちゃん! みたいな。成年向けでも姉モノ描きまくって世の姉好き族が持つ煩悩を見事に表現していた。……その威力は、年上に興味がまーったくなかった私を改心させたぐらいである。
因みに、『S-F マガジン』の新刊案内見てたら大ニュースが。『大久保町の決闘』(田中哲弥)がハヤカワ文庫から出たらしい! これは買いだろ! しかし今日立ち寄った書店では見受けられなかった。明日は絶対に買ってやる。そして読んでやる。
つーことでやってきましたよ『On Lisp』(Paul Graham オーム社)。早速明日から読み始める。一応導入部分をさらりと読んだが、本書の 3/2 はマクロの話なんだと。……すげ。今まで Lisp のマクロは全然触れたことがない領域なので、これからが楽しみになった。まあその前にもう少しきちんと『ANSI Common Lisp』も読んでおかないとね。実践は……まあ xyzzy と CLISP ないし GCL を使って。CLISP と GCL はどちらがいいかなーと模索中。
それではおやすみなさい。
今日も今日とて DOM Tetris 2(tetris.js
/ prototype_plus.js
)。ふと思い立って、バージョン1の時からあまり変えてなかったオブジェクトの構造を見直してみた。でもって継承構造をつくりなおした。
詳細は割愛するが、より抽象度を増したものに仕上げた。現状がベストかといわれればそうじゃないだろうなとは思うが、しかし前よりはマシになっているはず。コードをほとんど流用できたから、調整作業だけでなんとかなった感じ。
さて、給料も入ったし、本でも買いにいくかぁ。
お金がぜーんぜんないので『ラヴクラフト全集』も続きが買えず、最近はもっぱら以前読んだ本の3読目(以上)[1]で電車内と昼休みの時間を潰している。
やはりフィリップ・K・ディックの作品が好き[2]なのでよく彼の著作にここ6年ほど愛用している鹿皮のブックカバーをかけて鞄に入れていく。最近読みなおしたものは『高い城の男』と『流れよわが涙、と警官は言った』、それから『フロリクス8から来た友人』[3]に『銀河の壷直し』など。
因みに今日から読み始めたのは表題にもある『アルベマス』(東京創元社)。何を隠そうあの『ヴァリス』(東京創元社)の執筆される前まで書き続けられ、しかしバンタム・ブックスの編集者に改稿を命じられたが故に著者本人によって封印された代物である。このへんの事情については『アルベマス』巻末に付された『見果てぬ夢』(大瀧啓裕)や『フィリップ・K・ディックの現実』(ポール・ウィリアムズ ペヨトル工房)第9章に詳しい。他に、比較的入手容易な参考資料としては『まだ人間じゃない』(早川書房)巻末に付された『一九九二年のフィル・ディック』(木村重樹)があるが、情報が断片的なのでお薦めはできない。
『アルベマス』は、確かに改稿をあまりしていないというだけあって佳作といった雰囲気である。構成や会話もどこかぎこちなさが残っている。しかし一見狂人にしかうつらないニコラス・ブレイディの吐く言葉は、すべてディックが晩年に築き上げようとした救済神話に直結している。つまり『釈義』の人為的な要約版になっているわけだ。『釈義』が持つ意味の考察過程を延々と書いてある『ヴァリス』とはかなり違う。
とはいうものの、読んでいて飽きることはない代物である。断片的だが膨大な『釈義』の要約たる『アルベマス』は、それだけで一読の価値がある。
既に『アルベマス』は4読目だが、不思議と読み飽きたりはしない。実際のところ、まだ2回しか読んでいない本が最近多いのだ。どこのナニとは言わないが……。
まだ『アルベマス』は読み途中。明日で全部終えられるだろう。その次は何にしようか……。ああ、新刊があるんだった。30日には『Fate/Zero 2』(虚淵玄 Type-Moon Books)が出る。厚みの割には一段行間広めなので文字数が少ない。時間はかからないか……。あとは『On Lisp』(ポール・グラハム オーム社)かな? ようやく日本語訳版が書籍として登場。実は 2ch の Lisp スレで知ったのだ。即刻予約しましたよ。実はこいつが今一番楽しみだったりするわけだ。わくわく。
TimerExecuter
- DOM Tetris 2 のコードを少しばかりいじる時間もそこそこあったので DOM Tetris 2(tetris.js
/ prototype_plus.js
)の実装作業。ひとまずキーリピートを setInterval
でエミュレートするようにしてみる。ちょっと引っかかるのが気になるが、かなりいい感じに仕上がった。あとはタイマ用のオブジェクトを実装。まだ途中ではあるが、きちんと動いている(ENTER でスタート、p で一時停止)。
これらに使用しているのが、自作せざるをえなかったインターバル駆動を実装したオブジェクト、TimerExecuter
である。Prototype ライブラリの利用者ならわかるかもしれないが、これは PeriodicalExecuter
オブジェクトのアイデアをもらった再実装バージョンにあたる。何しろ PeriodicalExecuter
はどえらく使い勝手が悪いので、そのまま使えなかったのだ。継承作業は一切行わず、新規オブジェクトとした。ちなみに prototype_plus.js
に含まれている。
PeriodicalExecuter
との主な違いは次の通り。
new
しただけの時点では何も起こらない(スタートしない)start
/ stop
/ pause
メソッドを実装setInterval
に与えられる最小単位)start
メソッド実行時、タイマに関係なく1回だけコールバック関数が起動される最後に挙げたコールバック関数の起動に関する仕様は、スイッチ切替などにより ON/OFF を指定できるようにしようかとも思っている。その時々によってどうしたいか変わってくるだろうし……。
今週も金曜に飲み会か……。ここんとこ毎週のように飲み会があって嫌になる。食べたくもない料理、飲みたくもない酒を払いたくもない高い金(5000円とか……)で提供される。うう。今月は特に財布の中身がピンチだというのに。
以前にも GDI++ (Uploader) は話のネタに持ってきたことがある。だがあれからかなりの月日が経った。そんな GDI++、いつの間にか独自のレンダリングではなくフォントレンダラとして FreeType ライブラリを使うようになり、最近ではガンマ補正まで入れられるようになって、すっかりゴキゲンなのである。私にとって、GDI++ は「テキストを読む」ことが主体となる Web ブラウジングとエディタ上での作業には欠かせない存在である。資源を結構喰うので、残念ながら Firefox と xyzzy に適用してるだけだが。
現在 xyzzy 上では日本語フォントとして VLゴシック、英語フォントとして Courier New を使用。勿論 gdi++.ini
でそれぞれに別個の設定を持たせ、自分が一番いいと(今のところは)感じている状態にカスタマイズしてある。
GDI++ はじっくりと設定値を煮詰めてやればやるほどおいしく仕上がる。まだ FreeType を使う前のバージョンから、その設計思想は変わっていない。当たり前だが、それでいいと思うし、今の配布バージョンに添付されてくる gdi++.ini
には一応最低限の設定は書かれている。何も設定せずとも、ある程度まではそのパワーを享受できる。
勿論、本気になって設定を変えてやれば、その分だけ期待に応えてくれる。こういうカスタマイズ性が確保されている設計のソフトウェアこそが、確かなものとして残るんじゃないかと思う。GNU Emacs はそのお手本みたいなもんだろう。Vi 系列はまったく使ってないのでわからんが、あれもあれでいい具合に熟成させられると聞き及ぶ。
美しいフォントは、プログラミングの糧となる。カスタマイズできるソフトウェアは、自分好みに磨き上げる喜びがある。あとは OS ですかそうですか。本気で Vine Linux 入れないとね……でも時間が。
まあ観てきたわけですよ。渋谷のシネマライズまで。そしてびっくりしたわけですよ。これは下手すれば『新世紀エヴァンゲリオン』と同様に、アンチテーゼの物語として誤読され、消費されてしまうのではないかと。実のところ、両者は最終的に提示するものがとてもよく似ているという点で一致をみる。だが、『エヴァ』はただ単に「突き放す」物語であったのに対し、『秒速5センチメートル』のそれは肌触りこそやわらかく、しかしその本質は明らかに厳しく、我々に対してひとつのことばを囁くのである。
「こういうリアルも、あるんだよ」という、境界の瓦解を告げる囁きを。
Warning 以降の文章は、映画『秒速5センチメートル』のネタバレを含んでいます。
物語は短編三部作の形式をとっている。一応要約する。第一部は遠野貴樹と篠原明里の二人が離れ離れになった後、再開するまでの物語。前半の物語進行を担うのは貴樹に宛てられた明里の手紙が朗読される声。後半は貴樹の一人称。ここで貴樹と明里は桜の木の下でキスを交わし、再び別れる。第二部はその後の貴樹がどうなったかを綴る。但し語り部は貴樹が転校先で出合った少女、澄田花苗に移る。貴樹の一人称は登場しない。第三部はさらにその後の話。貴樹と明里が辿ったそれぞれの遍歴が提示される。その後半は山崎まさよしという歌手の楽曲と共に、それまでの貴樹と明里(+α)の時間が矢継ぎ早に観客の視覚へと叩きつけられる。
ここでまず特徴付けられるのが、語り部の視点が安定せず、従って観客にとっては感情移入の焦点が非常にあわせづらくなっていることだ。そもそもの第一部からしてこの特徴は顕著である。特に前半は、明里が貴樹に宛てて送った手紙の内容だけが一人歩きしている状況だ。合間に挟まれる会話なども、ほぼ全て過去の断片でしかない。そして後半になってようやく貴樹の一人称がメインになる。
手紙を朗読する声は、貴樹の脳内で再生されているものだ――と解釈することができる。例えば、手紙内容にあわせて明里の周囲が描写されない。観客が観ているのは、そのほとんどが貴樹の周囲である。その上、貴樹の手紙が朗読されるシーンは一度もない。
しかしあくまでも朗読の声は明里のものである。そこで観客の重心はすでにぐらついている。どちらか片方に重心をおくべきなのか、それとも両者に配分するのか。両者に配分するのは前述のとおりお門違いだし、しかし片方においても何だかしっくりこない。曖昧模糊とした状況が続く中で物語は一応の終わりを見せ、次に移る。
第二部では視点が澄田花苗に移る。花苗は貴樹に恋心を持っていたが、貴樹がそもそも自分を全く眼中に入れていないという事実に気がつく。観客にしてみれば「なんちゅう男だ!」となるだろう。こうして観客の感情移入は明里に移ってしまう。
だが問題は第三部である。ここで今度は、明示的に貴樹へと視点がシフトする。そうして彼が辿った道を、どんよりとした空気で見せられた後、再び視点のシャッフルが起こる。今度は貴樹と明里、更には花苗のものが入り混じり、ぐちゃぐちゃになる。
言い換えれば、特定人物への感情移入がとても難しいつくりになっているのである。
さて、次の特徴をみていこう。これまでの議論を踏まえたうえで、敢えて貴樹に視線(視点ではない)を固定してみる。そうすると、三部作の物語のうち二部までが、ほとんどいわゆる「美少女ゲーム」の様相を見せていることがわかる。第一部・二部ともボーイ・ミーツ・ガールのロジックにかなり忠実であるし、男が常にモテているという点も否定しがたいポイントだ。
だがこのロジックは視点の問題により完全にメタ化している。第一部では手紙朗読というファクターにより主体が完全に曖昧にされてしまった。第二部はそもそもの「攻略対象」たる女性側から見た「主人公」たるべき貴樹の描写になっている。あらゆる意味で逆転してしまっているのだ。更には花苗は完全に攻略対象から外されてしまっており、貴樹の世界に介入することができなくなっている。
最も重要なのは、第三部だ。第三部では「大人になった」貴樹の姿が描かれる。そこにあるのは、会社という組織で疲弊し、絶望し、ただ日々をなんとなく生きているだけの無気力な姿そのものである。ある意味、貴樹はバッドエンドへとひた走ったのだとわかる。こうして常に幸せにならなければならないという幻想は、静かに否定される。
三つ目の特徴は、同じ新海誠監督の作品である『ほしのこえ』との相似である。『秒速5センチメートル』でも手紙ないし電子メールが物語の端々に登場し、特に第一部ではかなりの発言力を誇っていた。『ほしのこえ』ではそれが全編にわたって登場し、物語の重要なファクターとして横たわっている。
だが『秒速5センチメートル』では、途中からほとんど手紙・電子メールという要素が希薄になっていく。第二部で、時折貴樹が電子メールを書いていると思しき描写が散見されるが、後にそれはどこにも送らず、ただ書いていただけのものだったことが判明する。『ほしのこえ』と異なるのはそこだ。『ほしのこえ』ではどれだけ遅延しても、どれだけ離れていても、必ず電子メールは授受された。つまり、「つながって」いられた。しかし『秒速5センチメートル』では、既に第一部のラスト近く、強風により貴樹が書いた手紙が彼自身の手から吹き飛ばされてしまった時点で、完全に明里との手紙を介したつながりが絶たれてしまった。別れ際、手紙を書くからという台詞を吐いてはいるものの、それが実行されなかったのは第二部ラストで完全に明らかとなる。また、第三部の楽曲シーンでも、空の郵便受けとポストをただ眺めるだけの二人が描かれ、その事実は補強されている。
つまり『ほしのこえ』では接続が、『秒速5センチメートル』では断絶が描かれたという見方ができる。もしあの時、手紙が吹き飛ばされていなかったら――という想像は容易である。しかし、『秒速5センチメートル』の世界はその if を許さない。ただ淡々と流れる時間が、それを痛いぐらいに物語っている。
四つ目の特徴は、『ほしのこえ』と同監督作『空のむこう、約束の場所』にみられた特徴、すなわち「セカイ系」の物語構造が皆無――ないしきわめて希薄――である点にある。第一部・第二部・第三部と描かれるのは、あくまでも今我々が生きているこの世界、この位相空間を背景につくりだした虚構である。しかし虚構であるからとはいえ、その中に SF 的なものやファンタジー的なものは一切含まれていない。その事実はさまざまなテクノロジや、それを体現する小道具で如実に示されている。いちばん大きいのは携帯電話の存在だろう。第一部には携帯電話が登場しない。それは貴樹と明里が子供だからという理由ではなく、大人にも携帯電話を使っている描写がない点からも、未だ普及していないことが明らかとなる。やがて第二部になり、貴樹が高校生になったときに出てくる携帯電話は、液晶画面がモノクロである。そして大人になった第三部では、ようやく現代のデザイン志向でつくられた携帯電話が登場する。つまりこれらの話は全て、映画館で映像を見ているよりも「過去」の話であると明示されている。そのうえ背景構造に追加は見られない。つまり何らかの「大きな物語」が動いている気配は微塵も感じられない。そこにあるのは我々が生きていくうえで過ごしているこの世界、何もない現実の完全なる模倣なのである。背景に何らかの「大きな物語」がない時点で、既にセカイ系という呪縛からは解放されている。映像の魅せ方、すなわち方法論は『ほしのこえ』や『空のむこう、約束の場所』と共通している部分が多いが、それだけである。
この事実は、もはやセカイ系の物語は語られなくなった(参照されなくなった)のではなく、物語がセカイ系である必要性がなくなったといった方が適切だろう。事実、この『秒速5センチメートル』という作品はそれらの束縛を受ける必要がない状態にある。逆に、束縛を受けていた場合は最終的に提示される「事実」が、完全に嘘くさいものになりさがってしまう。よって実際問題として、背景構造自体は昔からある恋愛ものであればいい。勿論、それが提示される状態は従来のファクターでは考えられないものであり、確実に「動物の時代」の洗礼を受けている。それだけは確認しておきたい事実である。
五つ目の特徴に移ろう。これは特徴というより、物語自体が最終的に発したメッセージのようなもの……いや、もっと曖昧でやわらかく偽装された「提案」のようなものだ。
それこそ冒頭に挙げた、「こういうリアルも、あるんだよ」という囁きである。
物語の終わり、第三部。ここでは明里のその後がはっきりと描かれている。しかし第三部の冒頭では少しぼかされている。明里が転校した先の田舎町、そこから電車に乗って東京へと向かう明里。その指には、婚約指輪。
そうして観客はだまされる。とくに、動物であることをためらわず、完全にその消費の中に身をやつしている類の人間は。私もある意味そうした人間の一人である。
やがて時間が流れ、場面は矢継ぎ早に切り替わる。……そして、楽曲シーンに入る。
そこで観客は驚くべき事実を突きつけられる。「貴樹が女性を一度つきあった後に振ったこと」、それから「明里の婚約者が貴樹ではないこと」である。
前者は完全に「美少女ゲーム」の論理から逸脱した行為である。故に『秒速5センチメートル』は動物の物語から断絶した。そこにあるのは現実の性交渉、男女間の諍いである。
何という生々しい提示であろう! しかもそれは非常に短いカットのなかで、断片的に示される情報でしかないのである。それはある意味、データベースの中にあるアイテムを連想させる。それらを繋ぎ合わせることに慣れきっている我々は、当然それらの「知りたくなかった」情報をも繋げてしまう。するとそれは垂れ流しの情報よりも素早く、確実に、しかも嫌らしいほどにありありと、「物語」の結末を告げてくる。
つまり、『秒速5センチメートル』という作品は、「ゲーム的リアリズム」の方法論で「自然主義的リアリズム」を描いた物語と言い換えられる。
理想の世界を構築し、安寧に浸る者にとって、この情報は毒でしかない。なぜならそれは今自分が生きている現実に、再び面と向き合わせようとするものだからだ。それも非常に遠回り――いや、ある意味でかなりのショートカット――な。
次に襲い掛かってくるのは、明里の婚約者の存在である。その存在は顔こそ隠されていた。……そこでまだ観客は救いを求めるのである。第三部の冒頭に挿入された、貴樹と明里の出会いのシーンによって。
出会いのシーンは電車が現れ、両者の姿が寸断された時点で次に移ってしまった。だが、完全なる最後、ラストのシーンで、もう一度その結末はリフレインされる。
貴樹が振り向いた先、線路の向こう側には、誰もいなかった。
そうして観客は絶望と喪失、そして決別を同時に味わうことになる。最終的に、明里の婚約者は貴樹でないことが判明してしまった。そもそも攻略すべきヒロインが存在しない美少女ゲームなど、存在しない。故に何度もいうようだが、この作品は現実の恋愛論に則って構築されている。随所に美少女ゲーム的な要素は含んでいるが、ただそれだけだ。前提条件が違うのである。
だが貴樹の表情は、それほど翳ってはいなかった。何故か。それは彼が大人――しかもゲーム的ではないリアリズムの上に成立する大人――になってしまったからである。夢想を夢想と断じ、理想に絶望し、恋人を喪失し、過去と決別する。
新海監督はこの作品を作ったことで、おそらく賛否両論に曝されるだろう。おそらく賞賛は、前日の日記のネタを使って言うならば「自然主義的リアリズム」を根底に持つ人間から。拒否は「ゲーム的リアリズム」(ないし「まんが・アニメ的リアリズム」を根底に持つ人間から。
しかしどちらの側にしろ、この作品は誤読されるだろう。この作品はどちらのリアリズムを賛美してなどいないからだ。ただ単に「こういう現実もあるんだよ」という事実を突きつけているだけなのだから。
……私の鳥頭なショボい記憶を頼りにここまで言説を構築してみたが、おそらく矛盾や間違い、もしかすると私自身が誤読している可能性もある。それだけは一応、註として。
とりあえず観てみての所感そのものは、面白かったということだろう。非常に甘酸っぱくて、久しぶりにもやもやとした気分になったものだが……[1]。そうでなければ文章など短く済ませてしまう。これでも決して長い方だとはいえないが、まあ時間もあまりないし、明日は仕事なのでそこそこ早く寝なけりゃなので、今日はこの辺で。
表題通り、『ゲーム的リアリズムの誕生 動物化するポストモダン2』(東浩紀 講談社現代新書)を読了した(以後略称『動ポモ2』)。前編にあたる『動物化するポストモダン オタクから見た日本社会』(以後略称『動ポモ』)も読んだ身としては、示唆に富んだ内容にかなり満足いった。
私の周囲には、こうした著作に関心を示す者がまだいないという認識だ。もしかしたらいるのかもしれないが、少なくとも話を振ってもレスポンスがない。こうした著作による批評や概念導入は、あらゆるものを考察するうえで使い勝手がいいツール(道具)として有効に活用すべきなのに。そうした意味で、哲学という分野はそれこそ太古から様々なツールを提供し続けている。知らずに利用せず遠回りをするよりも、ツールにより効率アップを図り、ショートカットした方が楽なのは当然だ。正規表現を使わずに文字列操作をするという馬鹿げた事態と考えれば、少しは理解してもらえるのだろうか。あるいはボール盤があるのに手動のドリルを使うようなもの、といってもいい。
事実、東氏も『動ポモ2』内で次のような発言をしている(強調筆者)。
(前略)筆者の関心は、オタクたちの特殊な文化を特殊な文化として紹介することにではなく、その特殊性に宿る普遍的な問題を抽出することにある。
『ゲーム的リアリズムの誕生』P23
(前略)とりあえずは筆者は、本書の議論で、二〇〇〇年代の物語はどのような状況にあり、どこに向かっているのか、そしてその分析にはどのような概念が必要で、それらの概念は批評の場でどう使われるべきなのか、かなりのていど明らかにしたことと思う。『動物化するポストモダン』の社会的な状況認識は、本書によって個別的な作品分析と接合されることとなった。読者はここから、かなり自由に、多様な批評の言説へと踏み出すことができるはずである。これ以降の展開は、ふたたび読者の手に委ねたい。
『ゲーム的リアリズムの誕生』P290
要は、ツールとして自著を使ってもらうことを完全に自覚している。
さて肝心の内容だが、第一章「理論」と第二章「作品論」の2章構成になっている。第一章では『動ポモ』以降の社会的状態と批評言説を取り込んだうえで、現在進行形の動物の時代[1](1995-)において生まれてきた新種の認識について解析と定義を行っている。すなわちゲーム的リアリズムである。そのうえで、少なくとも前述のような新種のリアリズムが存在しているという前提で批評を展開すれば、新種のリアリズム上に成立している作品が批評可能になるとする。言い換えれば、旧来のリアリズム認識(すなわち自然主義的リアリズム)だけを前提とした言説では批評不可能なものが存在するようになった。
またゲーム的リアリズムが成立する以前(すなわち動物の時代以前)、まだ虚構の時代(1970-95)であった頃に発生してきた認識であるまんが・アニメ的リアリズムについて詳細な解説が行われている。まんが・アニメ的リアリズムが生み出した土壌を用いて生まれたのがゲーム的リアリズムであるからだ。
第二章では個別の作品について、第一章で導入した概念を用いた読解・批評がなされる。主題として挙げている作品は次の通りだが、時折別の作品の話に入ったりもする。
2読目はこれからだし、所々疑問に思うところがあったので手放しに賞賛することはできないが、1読目の所感としては、かなりまとまった論考でバランスもそれほど悪くはない。なにはともあれ1度は読んでみるべき著作である。ただ、その前に最低でも『動物化するポストモダン』を読んでおくと、より理解しやすい。
さて、明日は映画でも観に行くかね。
常用 UA を Gran Paradiso Alpha 2 に変えてみた。拡張機能も全部バージョンチェックを誤魔化して利用できている。特に問題はないかな……と思ったら、GDI++ (FreeType Ver.) を使うとまあ文字のレイアウトがフォントによってはぐちゃぐちゃになるわなるわ。どえらいことになってしまったので gdi++ は使わないようにした。……折角の美しいフォントレンダリングが。畜生。
ひとまず移行完了したので使ってみる。うん。結構いい感じ。ブラウジングに関しては特に問題ないようだ。使い込んで落ちたらレポートツールでデータ送信すればいいし。
一応書いておくが、あくまでも Gran Paradiso Alpha 2 は先行評価用。実用に耐えうるものではないし、そのつもりもない(それでもアルファ品質でここまで安定しているのは流石だ)。私のように常用するのは非推奨。
Function
の謎は全て解けた! - 最近の言語いじり事情先日の続き。
ECMA 262 3rd Edition では、Function
プロトタイプオブジェクトは Function
オブジェクト自身であると定義されていた。
ここで見落としてはならないのが Function
オブジェクトという言い回しだ。そこには、どこにも「Function
オブジェクトのコンストラクタ」とはかかれていない。つまり、「Function
オブジェクト」が意味するのは「Function
オブジェクトのコンストラクタによって生成された Function
オブジェクト」なのである。
例えば Function.prototype.prototype
プロパティにあるオブジェクトについて考えてみよう。Gecko でも何でもいい。JavaScript 処理系に alert
なり何なりさせると、 Function.prototype.prototype.prototype === undefined
となる。だが、Function.prototype.prototype.[[Prototype]] === null
なのだ[1]。
つまり Function.prototype.prototype === Object プロトタイプオブジェクト
であるといえる。ECMAScript において、[[Prototype]]
が null
をとるオブジェクトは、Object
プロトタイプオブジェクトの他に存在しないからだ。
ぶっちゃけて言えば、Function.prototype = new Function();
なのである。
そんなアホな、というなかれ。ECMA 262 3rd Edition 仕様とにらめっこすれば、確かにその通りになっているのである。
そもそも new Function()
はどのような動作をとり、どのようなオブジェクトを返すのか? 答えは仕様書の 15.3.2.1 と 13.2 にズバリ書いてある。次に引用する(日本語訳版、強調筆者)。
- (略)
- (略)
- (略)
- (略)
- (略)
- (略)
- (略)
- (略)
- (略)
- (略)
- (略)
- (略)
- (略)
- (略)
- (略)
- FormalParameterListopt として P を解析したもの、 FunctionBody として body を解析したものをパラメータに渡し、13.2 に規定されるように、新規 Function オブジェクトを生成する。Scope パラメータとしてグローバルオブジェクトから構成されるスコープチェーン内を渡す。
- このセクションのアルゴリズムのこれまでの呼び出しで生成されるオブジェクト E がすでに存在している場合、そしてその、このセクションのアルゴリズムの呼び出しが、今回与えられた FunctionBody と等しい FunctionBody を与えられた場合は、ステップ 13 へ。(これらの判定基準を満たす一つ以上のオブジェクト E が存在するならば、実装の裁量の一つを選択する)
- 新しい ECMAScript オブジェクトを生成し、 F をそのオブジェクトとする。
- F の [[Class]] プロパティを "Function" に設定する。
- F の [[Prototype]] プロパティを、セクション 15.3.3.1 に定義する、オリジナルの Function prototype オブジェクトに設定する。
- F の [[Call]] プロパティを、セクション 13.2.1 に述べるように設定する。
- F の [[Construct]] プロパティを、セクション 13.2.2 に述べるように設定する。
- F の [[Scope]] プロパティを、 Scope と同じオブジェクトで構成される新しいスコープ連鎖(10.1.4) に設定する。
- F の length プロパティを、FormalParameterList に指定される形式的プロパティの数に設定する。パラメータが指定されなければ、F の length プロパティを 0 に設定する。このプロパティは、セクション 15.3.5.1 に定義される属性を与えられる。
- 式
new
Object() により生成されるかのように、新しいオブジェクトを生成する。- Result(9) の constructor プロパティを F に設定する。このプロパティは 属性 { DontEnum } を与えられる。
- F の prototype プロパティを Result(9) に設定する。このプロパティは、セクション 15.3.5.2 で定義される属性を与えられる。
- F を返す。
- (後略)[2]
こうして返されたオブジェクトは、その prototype
プロパティに Object
オブジェクトを持つ Function
オブジェクトである。故に Function.prototype.prototype
は Object
オブジェクトの prototype
プロパティなのである。
あー! まったくもう! ようやく謎が解けたよ。そしてそれを確証にまで発展させるのに時間がかかったうえ、昨日は滅茶苦茶疲れててろくに思考もできなかった。今日は何とかこうして書いてる。でもまとまってないなぁ。
もう最近関数とオトモダチな言語ばかりいじってる。というよりも、そうでない言語に全く興味を持てない。
つい先日から、ようやく Ruby にも手を出し始めた。小括弧だらけでもなく、かといって中括弧が頻繁に現れるわけでもない、ちょっと不思議な感覚。Perl も結構中括弧多いもんね。Ruby は出し始めだから、基本文法を少しばかり齧って、クロージャをいじったぐらいだけれども、噛んだときの柔らかさは Perl より硬めな感じ。それが魅力でもあるとは思うけど。
……そうすると益々 Java (Sun がプッシュしてる方ね)なんかいじろうとしなくなってるな。いや、だってさ。こう言っちゃナンだけど、いまいち魅力を感じられないのよ。コードを読んだ感じ、正規表現ひとつ使うのもしち面倒っぽいし。そういうと C++ も同じか。どんどん Perl と JavaScript と Lisp (Common Lisp & Emacs Lisp) にのめりこんでる状態。
コード書いておまんま喰うには、Java もある程度やっとかんと駄目か? ……うーん。覚える気がない言語を無理してやろうとしても身につかないのがオチだ。やりたいようにやるさ。ひとまず Java は放置で。
私の「やりたい言語キュー」にはまだ中身がたっぷり詰まっている。筆頭は Ruby、次に Haskell、更には C++ で最後に Ada。いや、Ada は本当に何となくだけれども。面白いかなーって。コードを見る限りでは石頭ここに極まれりっていう体だったが。はてさて。
[[Prototype]]
⇔ __proto__
の前提で話をしている。Array
プロトタイプオブジェクトの謎は解けた結論としては、私の勘違い。なぜなら、例外を除き、ほとんどの場合prototype
プロパティはコンストラクタにしか含まれない からであり、そもそもコンストラクタではない Array
プロトタイプオブジェクトには prototype
プロパティが含まれていない。それは Object
プロトタイプオブジェクトも同じ。
Array プロトタイプ Array オブジェクト オブジェクト +---------------+ +---------------+ | prototype | | | | +-+ | | | | |+------------->| | | +-+ | | | | | | | | [[Prototype]] | | [[Prototype]] | | +-+ | | +-+ | | |+| | | |+| | | +|+ | | +|+ | +------|--------+ +------|--------+ | | : :
先程「例外」と記述したが、確かにプロトタイプオブジェクトなのに prototype
プロパティが参照できてしまうものがある。それは Function
プロトタイプオブジェクトだ。
先日も引用した仕様書の記載によれば、The Function prototype object is itself a Function object (its [[Class]] is "Function") that, when invoked, accepts any arguments and returns undefined.
である(強調筆者)。つまり、Function
プロトタイプオブジェクトは Function
オブジェクト自身 なのだ。よって Function.prototype.prototype !== undefined
なのである。
しかし、腑に落ちない点がなかったわけではない。ここで第二の疑問が発生してしまったからだ。何故 Function.prototype
が Function
オブジェクト自身であるならば、どうして Function.prototype.prototype.prototype
は undefined
なのだろうか?
先程引用した仕様の文面を額面どおりに受け取ると、Function
プロトタイプオブジェクトの prototype
プロパティは、自分自身を参照することになる。なぜなら、Function
オブジェクトの prototype
プロパティは Function
プロトタイプオブジェクトを指し示すからだ。
Function プロトタイプ Function オブジェクト オブジェクト +-----------+ | | v | +---------------+ +---------------+ | | prototype | | prototype | | | +-+ | | +-+ | | | |+------------->| |+-----------+ | +-+ | | +-+ | | | | | | [[Prototype]] | | [[Prototype]] | | +-+ | | +-+ | | |+| | | |+| | | +|+ | | +|+ | +------|--------+ +------|--------+ | | : :
だが、この考え方はおかしいことがはっきりとしている。そもそもコンストラクタにしかないはずの prototype
プロパティが、どうしてプロトタイプオブジェクトに存在しているのか? そもそも、prototype
は必ず null
に行き着かねばならないのに、どうして無限に循環し続けるような構図になっているのか?
実は、答えは先の引用に全て書かれていた(暗黙の、ではあるが……)。私はそれを見落として、前述の考えに至り、矛盾が出た。
次回に続く……と思う。
Array
プロトタイプオブジェクトの謎今、継承に関する文書を書いている途中で気づいたのだが、どうやらArray
プロトタイプオブジェクトの具体的な定義が曖昧のように感じられて仕方がない。ECMA 262 3rd Edition の仕様書(邦訳)を読んだだけで判断しているのだが、ちょっとわからなくなったので今日はこれをネタにしてみる。
問題になっているのは、Array
オブジェクトの prototype
プロパティに入るオブジェクト。いわゆる「Array
プロトタイプオブジェクト」……そのオブジェクトが持つ prototype
プロパティに入るオブジェクトだ。
Array プロトタイプ Array オブジェクト オブジェクト +---------------+ +---------------+ | prototype | | prototype | | +-+ | | +-+ | | |+------------->| |+-------------> ??? | +-+ | | +-+ | | | | | | [[Prototype]] | | [[Prototype]] | | +-+ | | +-+ | | |+| | | |+| | | +|+ | | +|+ | +------|--------+ +------|--------+ | | : :
ECMA 262 3rd Edition において、Array
プロトタイプオブジェクトについての言及は次のようになっている(強調筆者)。
Array プロトタイプオブジェクトの内部 [[Prototype]] プロパティの値は、 Object プロトタイプオブジェクト (セクション 15.2.3.1) である。
Array プロトタイプオブジェクトはそれ自身が配列である; その [[Class]] は "Array" で、 length プロパティ (初期値は +0) とセクション 15.4.5.1 に述べる特殊な内部 [[Put]] メソッドを持つ。
プロトタイプオブジェクトのプロパティである関数の説明において、以降フレーズ "このオブジェクト" は関数実施の this 値であるオブジェクトを参照する。内部 [[Class]] プロパティの値が "Array" でないオブジェクトであることが this に許可される。
NOTE Array プロトタイプオブジェクトは独自の valueOf プロパティを持たない; だが、 valueOf プロパティを Object プロトタイプオブジェクトから継承する。
同じ箇所を、今度は英語原文から引用してみる(強調筆者)。
The value of the internal [[Prototype]] property of the Array prototype object is the Object prototype object (15.2.3.1).
The Array prototype object is itself an array; its [[Class]] is "Array", and it has a length property (whose initial value is +0) and the special internal [[Put]] method described in 15.2.3.1.
In following descriptions of functions that are properties of the Array prototype object, the phrase “this object” refers to the object that is the this value for the invocation of the function. It is permitted for the this to be an object for which the value of the internal [[Class]] property is not "Array".
NOTE The Array prototype object does not have a valueOf property of its own; however, it inherits the valueOf property from the Object prototype Object.
15.4.4 Properties of the Array Prototype Object
強調部を同じ意味の部分にあわせた。
これの何が問題かというと、Array
オブジェクトだけはそのプロトタイプオブジェクトのプロトタイプオブジェクトが自己参照をおこなっていないのではないかという疑惑に行き着いてしまうのである。
例えば、Function
オブジェクトを例にとってみよう。英語原文では次のような表記がなされている(強調筆者)。
The Function prototype object is itself a Function object (its [[Class]] is "Function") that, when invoked, accepts any arguments and returns undefined.
15.3.4 Properties of the Function Prototype Object
そう。きちんと「Function
オブジェクト」であると明記しているのである。
対して Array
プロトタイプオブジェクトのそれは、「配列」であるとしか書かれていない。英語としては「object」という単語がない上に、「array」は先頭が大文字でないから固有名詞(オブジェクト名)でなく、一般的な「配列」という単語として解釈しなければならなくなる。
確かに ECMAScript における「配列」は、Array
オブジェクトが実装してくれている。……しかし、だからといってそれが Array
プロトタイプオブジェクト自身であるという証拠にはならない。何故なら明言されていないからである。
以上の事実から、「Array
プロトタイプオブジェクトの prototype
プロパティの値」には、ふたつの候補があることになる。
Array
プロトタイプオブジェクト」自身……まあ、他と同様な解釈をとれば 1 なんだけれどもね。それでも、2であったとしてもそれはオブジェクトであることにかわりはなく、つまるところ矛盾はしないから成立してしまう。困ったもんだ。明記してくれなければわからないじゃないか。
もう少しじっくり考えてみよう……。
つまり「about:mozilla
勝手に解釈」の書き直し。非常にためになるというか私の認識が間違っていた部分があるというか。今のところ日本語に訳されてはいないようだ。何より驚いたのは、十二章十節 (12:10) が書かれたのが December 10, 1994, すなわち1994年12月10日だということだ。……だから12:10 だったのか。それはそうなのだが、この時代は Netscape 1.0 の全盛期である。しかもコメントによれば Netscape 1.0 のリリース日である。つまり、文面の内容は別段アノ会社への嫌味でも何でもなかったわけだ。しかし当時は NCSA Mosaic への闘争心が燃え盛っていた頃であろう。そういう意味では、もっと純粋な(といってもブラックジョークのそれだ)心境で書かれていたことは想像に難くない。ふたつの意味で捉えられる、いい意味でも悪い意味でも Mozilla という怪獣の歴史を体現している文書――書き直ししたくてたまらなくなってきたな。
ただ、真偽のほどは定かでないため確認は必要。とりあえず Netscape 1.1 あたりを手に入れようと考えている。話はそれからだ。Wikipedia の記事を参考にしつつも、今のスタイルは崩さない方向性で。
ふたつの文書(JavaScript の継承云々のアレ)を同時進行か。まあ、どうにかなるべ。
2007 年 4 月から、my-sv.net ドメインでは自動広告強制掲載が始まってしまうため、サイトを移転させました。新しいアドレスは http://freeserver.name/~eof/ になります。RSS を取得されている方、アンテナに加えていただいている方、ブックマークされている方は、お手数ですが新アドレスへの変更をお願いします。
しばらくの間は my-sv.net の方にもコンテンツを置いておきますが、今後の更新は freeserver.name/~eof/ のみ行います。my-sv.net ドメインの更新はしません。
当サイトを閲覧していただいている皆様のご協力をお願いします。
……以下移転理由や謝辞など。
それにしても、広告掲載が本当に始まるとは思ってもみなかった。あと一ヶ月ほど時間はあるものの、早めに動いておいたほうがいいと思い至り、他の「広告なし・無料・CGI 可・SSI 可」のところを探したところ、freeserver.name という場所を見つけ出した。早速スペースを貸していただくために交渉。……驚くのはここからだ。
申請を出したのが3月3日の20:55。そして返事を受け取ったのが3月4日の00:42。……何というスピードか。あっという間にOKをいただいたのである。ここに、改めてサーバ管理者である pAgRu 氏に礼を言わせてもらおう。ありがとうございました。
移転作業もローカルにある最新データを FTP するだけだったので、CGI の調整含め1時間足らずで終了。いやはや。何とかなるもんですな。
広告の強制掲載は、私のように「自分の XHTML 文書は自分でコントロールしたい」と考えている人間にとっては、邪悪ともいえる行為になる。他人によって知らぬうちに意図しないコードが埋め込まれる。……背筋が凍りつくほどの恐ろしさだ。埋め込まれるコードが仕様に厳格であるという保障はまるでなく、どの部位に入れられるかもわからない。文書構造を崩されては、いくら自分が気をつけていたところで元も子もない。例え全ての仕様が判明したとしても、そもそも不要なマークアップが施されるという時点でアウト。折角今まで年月をかけて磨き上げてきた文書構造を、破壊されたくはないのだ。
だが「やめてくれ」といったところでどうにもならない。そのため、今回は防衛策をとったということになる。
一応 .htaccess にリダイレクトを指示する構文を埋め込もうと画策中。移転した旨を伝える文書を、別途作成して、そこに飛ばすようにしようと思っている。まだ処理してはいないが、おいおいやるつもり。
さて、明日から仕事だ……。何だか休みがあっという間に過ぎていくなぁ。
今日は Mozilla Developer Center (MDC) の JavaScript 1.5 ガイドを流し読み。特に、最近色々と気になっていた継承に関するところはじっくりと読んだ。継承に関していろいろ書いてあるが、予め情報として知っていたとはいえ、ここまで綺麗にまとめてくれてあると逆に助かる。しかも例を挙げて実装面にまで踏み込んだ解説もされている。いささか読みにくいという難点はあるにしても、ある程度 JavaScript について経験と知識を持つ人間なら「なるほどね」となる。無論、初学者が読めばチンプンカンプンなのは目に見えているが……。
継承については特に最近色々と勉強になった事も多いので、ここで少しまとめてみようと思い立った。まずはわかっていることから。
JavaScript において、プロパティの継承にはいくつものやり方が存在する。for-in を用いる方法、__proto__
を用いる方法、new
を用いる方法……まさに「やり方は、ひとつじゃない」状態である。本稿では主に2つのやり方、「__proto__
を用いた継承」と「new
を用いた継承」について紹介する。
__proto__
を用いた継承最も単純であるが、汚い方法。私が知る限りでは JavaScript 1.5 に準じた処理系なら使えると思われる[1]。但し ECMA 262 3rd Edition (ECMAScript) の仕様には記載がないため、ECMA 262 3rd Edition に準じた処理系では使用することができない。故に、最良の方法ではないため非推奨とする。
次のようにして継承作業を行う。
// 継承元(基底) // 親オブジェクト function Position(x, y) { this.x = x; this.y = y; } // Position END Position.prototype = { toString : function() { return "Position"; } }; // 継承先(派生) // 子オブジェクト function Cell(x, y) { // 親オブジェクトのコンストラクタを明示的に呼び出す Position.apply(this, [x, y]); } // Cell END // 継承 - for "__proto__" Cell.prototype.__proto__ = Position.prototype; // Cell.prototype = { ... }; と、プロパティを一気に入れようとしてはならない // prototype の中身を全部上書きしてしまうため // -> 結果的に継承できたものまで消してしまう // 次のように、ひとつずつ追加しなければならない Cell.prototype.toString = function() { return "Cell"; };
1行追加するだけである。必要に応じて親オブジェクトのコンストラクタを呼び出して初期化を肩代わりさせたり(apply
を使用している部分)、プロパティを追加・オーバーライドさせたりする。
ただ、前述のようにこの方法は特定の環境でしか用いることができない。例えば IE は __proto__
を持っていない実装(JScript)なので、全く意味がない行為になってしまう。そうした場合に効果を発揮するのが、次に紹介する「new
を用いた方法」である。
new
を用いた方法MDC のドキュメントでも紹介されているぐらいにはポピュラーであり、ECMA 262 3rd Edition に準じた処理系ならまず使えるであろうと思われる方法。
次のようにして継承作業を行う。
function Position(x, y) { this.x = x; this.y = y; } Position.prototype = { toString : function() { return "Position"; } }; function Cell(x, y) { Position.apply(this, [x, y]); } // 継承 - for "new" Cell.prototype = new Position; Cell.prototype.constructor = Cell; Cell.prototype.toString = function() { return "Cell"; };
2行追加するだけである。こちらも必要に応じて親オブジェクトのインスタンスを呼び出して初期化を肩代わりさせたり、プロパティを追加・オーバーライドさせたりする。
この方法はきわめて優秀で、今のところ Firefox / Opera / IE といった有名どころの UA が持っている JavaScript (JScript) 処理系なら問題なく利用することができる。Konqueror (KHTML) や Safari (AppleWebKit) では確認していない(が、恐らく大丈夫だろう)[2]。
prototype
同士の代入を用いる方法 - うまくいかないここまで読んできた読者の中には、次のようなコードを脳裏に浮かべた方もいるだろう。
Cell.prototype = Position.prototype;
確かにこの方法は実行エラーにはならない。だが、致命的な欠陥を持っている。例えば、次のコードを考えてみる。
function Position(x, y) { this.x = x; this.y = y; this.str; } Position.prototype = { toString : function() { return "Position"; } }; function Cell(x, y) { Position.apply(this, [x, y]); } // やってはならない継承もどき Cell.prototype = Position.prototype; Cell.prototype.toString = function() { return "Cell"; }; var p = new Position(); var c = new Cell(); // 絶対に意図した動作にはならない alert(p.toString()+" : "+c.toString()); // Cell : Cell
つまり、プロトタイプチェーンが全く同一と化してしまった2つのオブジェクトでは、どちらかが prototype へ及ぼした影響が他方にも伝播してしまうのだ。これでは継承もへったくれもない、ただの共有のようなものである。とてもではないが使うことなどできはしない。故に「うまくいかない」方法に成り下がっているのである。
今回の「導入編」では、次の事項について記述した。
__proto__
を用いた継承の方法new
を用いた継承の方法prototype
同士の代入ではうまくいかない次回「理論編」では、どうして今回紹介したような方法で継承を実現できているのか、また実現できなかったのかについて、より詳細な視点から突っ込んだ話をしてみる。
……はいそこ寄せ集め情報のうえにパクリっぽいとか言わない。気にしてるんだから[3]。
constructor
が上書き不可であるというバグのため、この方法に欠陥が生じる(使えなくもない。理由は「理論編」で)。但し Rhino 1.6R2 では fix されている。その他の処理系については調査していない。ほんと、Opera のキーバインドには悩まされるね……。 DOM Tetris 2(tetris.js
/ prototype_plus.js
)は現在イベント周りの改良中。今日はキーイベント処理をもちっと UA に依存しないつくりにしようとがんばってみた。
まず問題となるのが UA ごとの処理が違ってきてしまうことだろう。素直なやりかたでイベント処理をやろうとすると、Gecko や Trident (IE7) では OS のキーリピート設定がモロに表面化し、Trident (IE6) では keyup
するまでブロックが移動してくれない。最悪なのが Presto で、こいつは他のキーバインドが優先権を奪っているのでその影響もあってかまともに動かない。
仕方がないのでキーリピートに関しては自前で実装してみようと思い至った。しかしこのアプローチは、既に DOM Tetris (ver. 1.x) で既に行われているものだ。今回はより処理がしやすく後腐れが少ない実装にしようとした。
結論から述べよう。Presto では再びまともに動かなかった。それどころか前より悪くなっているぐらいだ。ちょっと複雑な操作をするとイベントリスナがステータスがあがってくるのを追いきれなくなり、それは setTimeout
や clearTimeout
でも同じことがいえるらしく、操作ロックしたうえに延々と直前の動作をとろうとするので、自動スクロール状態になってしまったりする。まことにもって忌々しい。
現在代替案を検討中だが、これといって有益な考えが浮かばない。……他の Ajax アプリケーションはどうしているのだろう。やはりライブラリか。Prototype はイベント周りに関しては弱いという話をきいたことがあるので、もっと強力なものを引っ張ってくるか、自前で解析して取り込むか、とにかくどうにかしてやらねばならない。
ああ……どうしよう……。シャワーでも浴びてからゆっくり考えるべ。