JavaScript: どんな型の値でもとりあえずメンバフィールドに値を突っ込んでみるテスト ― 2010年08月05日 13時06分43秒
えー。長らく更新をサボって申し訳ない。しかも今回の内容は完全に個人的なメモなのでなおさら申し訳ないw
JavaScript って割とオブジェクト指向的な性格の強い言語だと思うんだけど、いわゆるオブジェクト型の値に限らず、関数型の値であってもメンバフィールドを持つことができたりして、その辺どうなっているのか、っていう辺りを整理しておきたかった。
で、以下のような HTML を書いてみたわけだ罠。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0//EN"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <meta http-equiv="content-style-type" content="text/css"> <meta http-equiv="content-script-type" content="text/javascript"> <title>member field test</title> <script type="text/javascript" language="JavaScript"><!-- window.onload = function() { var table = document.getElementById("result"); if (table.firstChild.nodeName.toLowerCase() == "tbody") // IE6 対策 table = table.firstChild; var testdata = [ 1, "", true, undefined, null, Infinity, NaN, function() {} ]; for (var i = 0; i < testdata.length; i++) { var tr = document.createElement("tr"); // 値を表示 var td = document.createElement("td"); td.appendChild(document.createTextNode( typeof testdata[i] == "function" ? testdata[i].toString() : typeof testdata[i] == "string" ? '"' + testdata[i] + '"' : testdata[i] === null ? "null" : // Gecko はこうしないと空欄になっちゃうので… testdata[i])); tr.appendChild(td); // 型を表示 td = document.createElement("td"); td.appendChild(document.createTextNode(typeof testdata[i])); tr.appendChild(td); // フィールドへの代入を試みる td = document.createElement("td"); var result; try { testdata[i].hoge = "Hoge!!"; result = testdata[i].hoge; } catch (ex) { result = ex.toString(); } td.appendChild(document.createTextNode(result)); tr.appendChild(td); table.appendChild(tr); } }; //--></script> </head> <body> <table id="result" frame="border" border="1" rules="all"> <tr><th>値</th><th>型</th><th>x.hoge</th></tr> </table> </body> </html>
結果はこんな感じ。一応 IE6、Firefox、Safari にて動作確認済み。
結論をまとめると以下の通り。
- ブラウザ間で動作の差異は見られなかった。
null
の動作が意外なほどundefined
の動作に酷似している。オブジェクト型のくせに。ていうか、全くの別物なのに。- メンバフィールドに入れた値をその後も利用できるのは、通常のオブジェクト型の値を除けば関数型の値のみ。
- 数値、文字列、真偽値については、メンバフィールドへの値の代入のようなことをやっても例外は発生しない。が、あとでそのフィールドを参照すると
undefined
が返される。中途半端な動作だな。undefined
とnull
は代入しようとした時点で例外が発生。- ついでに言うと、
undefined
とnull
はtoString()
メソッドを適用することもできなかった (例外を送出する)。undefined
についてはそも値ではない (より厳密には「インスタンスではない」) からということで納得がいくんだが、null
についてはなんだろ…オブジェクトなんだけどオブジェクトじゃないものであるということをことさらに表現したい、ってことなのか??
- ついでに言うと、
ネットとバーチャルの混同 ― 2010年08月10日 04時39分26秒
はてなブックマークを利用するようになってから、ニュース記事や余所のブログへの言及記事を滅多に書かなくなってしまった。とまぁ、そこまでは別に気にしていなかったのですが、はてなハイクや Twitter をやるようになってから、今度はブログ自体をほとんど書かなくなってしまい、今に至ります。
ハイクも Twitter も、一度 post したら修正不可能なメディア。特に Twitter なんて文字数制限があるわけで、長文を綴るのには向かないツールなのに、何故かつらつらと長文を書きたくなってしまうことがちらほら。なんというか、あの何となくだらだらととりとめもなく書き綴る感じが、どうせ修正できないんだから校正とか考える必要ないかーみたいな投げやり感が、そして興味のある方がその場で割と手早くレスポンスを投げてくれるライブ感が、おいらをそうさせてしまったんだろうなぁとか思ったり思わなかったり。
いずれにせよ、ブログに書いておけばよかった級の長文が、この手のメディアで細切れ状態で漂うのはなんかもったいないので、今後はなるべくブログに書くようにします。ていうか、JASRAC 絡みの能書きなんて後でブログに起こす気満々だったんジャマイカ…もう今更だなぁ…どうしようこれ。
んで、こういう場でちゃんと長文を書くのもなんとなーくリハビリが必要な気がしたりするのでw、しばらくはとりとめもない話題でいくつか書いてみようとか思ったりする。あーブログ書くのひさびさできんちょうするなー (棒読み)。
割と昔からよく目にする構文なんですが、「ネットとリアルの混同」って奴。これって多分、ネット上でのやりとりが強いストレスになるケースがあって (2ちゃんでマイノリティ扱いされたとか、ブログなり Twitter なりで糞の投げ合いになっただとか、匿名でやっていた恥ずかしいことがハンドル名レベルで暴露されたとか)、それを実生活に引きずるが故に、仕事に支障が出たり、家族と喧嘩になったりするような、そういうケースを指してよく言われた言葉なんだと思う。
しかしまぁ、元々の表現方法自体に問題があるからだと思うんだけど、この言葉はたいていの場合、発言者の都合のよいようにネットと実生活を「別物」として扱いたい場合に用いられているのが実情なんだと思う。最近の使用例で思いつくのは、まぁこの辺とか。
百戦錬磨のネット論客 (笑) であるならば、そもそもネットはバーチャルでもなんでもなく、普通にリアルで利用されているツールというかメディアに過ぎない、ってことをよく理解している。だからネット上での発言も慎重なものになるか、あるいは極力自分で責任を持とうとする。間違いが指摘されれば調べ直して反論したり適宜修正を加えたり、とか。
だから、上記のようなケースは、それがネットであるが故の問題なのではなく、単に「プライベートと仕事を混同」しているだけだ、ということはすぐ理解できる。
ただ、ネットを「ある程度」バーチャルな空間として許容する空間もある。いや、空間と言うよりも、それは個々人の使い方によるもの、と考えた方がいいかもしれない。それは何かというと、匿名での参加および情報発信、である。
もちろんこれは、ハンドル名を用いて本名、素性を隠しているケースでも当てはまるんだけど、一連の発信内容から個人が特定されるリスクが高まることを思えば、完全な名無しさんの方が「バーチャル度」は高い、と言えるのかも知れない。匿名でネットを利用する人たちは、ネット上での発言や行動について、多くの場合その責任から逃れることが可能である為、ネット上での行動を、夢や妄想などの、実生活とは異なる概念として、精神的に切り捨てることができる。で、そういう使い方に慣れている人に限って、「ネット」と「バーチャル」を混同してしまうのではないかと思う。
いや、感覚的には割と前から漠然とそんな風に思っていたんだけど、こうしてしっかりと言葉にできるほどではなかった。
で、ネットでトラブルが起こるケースというのは、まさにこの、個々人が勝手に想定している「バーチャル」の領域と、社会の全体または一部、あるいは社会システムにおいて強い権限を持つ組織や個人が持ち込む「リアル」の領域とが、互いに衝突することによって生じているのではないか。例えば、ネットをバーチャルだと捉えすぎてしまったが故に暴走するケースとして、 OFF 会での悪ノリなんかが挙げられると思うし、領域の見極めに失敗したが故にトラブルとなるケースとして、 mixi でのダメ武勇伝 (犯罪行為とか) の開陳や、公私混同の動画うp (メガ盛りとか) による解雇などが挙げられると思うし、さらには公権力などの強い権限がバーチャルに過度に干渉するケースとして、犯行予告ジョークの度重なる摘発などが挙げられるんではないかと思う。
これらは当該ネット利用者からしてみれば、バーチャルだと思っていたものが突然リアルとして牙をむくわけで、言ってみれば悪夢を観て本当に死んでしまうグレイルクエストのような理不尽感なのだと思う。いや、七つの奇怪群島とか、めっさお気に入りでしたけどね。
そんなわけで、思い当たる節のある方なんかは、十分お気をつけくだちゃれ、ってなわけで本文を締めさせて頂きたいと思います。めでたし、めでたし。
目的指向プログラミング ― 2010年08月14日 13時53分57秒
からリンクを辿って
を読み、ブクマで糞を投げてみたものの、年配の日本人プログラマーにおいては割とありがちな傾向なのではないかと思うところもあり、ちょっと書いてみようかしらとか思った次第。
オブジェクト指向にありがちな、それもとっても日本人的な誤解のひとつに、「オブジェクト = 物、物体」という解釈があると思う。確かに object という英単語には「物、物体」という意味があるのだけれど、実際には物体を表現しているわけではないオブジェクトについてまで、それを物体だと見立てて思考展開するんだ、と無理矢理自分を納得させながら Java や C# やその他のオブジェクト指向 (に対応した) プログラミング言語で頑張っている人って、実は若手でも少なくないんじゃないかと思う。
object という英単語には他にも「対象」や「目的、目標」などの意味がある。そのことを踏まえた上で、オブジェクト指向による設計について考えてみて欲しい。
例えば Window
という名前のクラスがあるとする。このクラスの概要を説明する際、大抵の人は「ウィンドウを表すクラス」と書いてしまうのではないかと思う。これは多分、「オブジェクト = 物、物体」という前提をかなり意識した書き方だと思う。
あるいはポリモーフィズムを意識している人ならばもう少しマシに、「ウィンドウを表す基本クラス」などと書くかも知れない。そして派生クラスとして、FrameWindow
があったり、 DialogBox
があったり、はたまた見た目にも概念的にもウィンドウとは似ても似つかない FormControl
なんてのがあったりするかも知れない。それでもこれらは「ウィンドウを表すオブジェクト」の一種をインスタンスとして生成するためのクラスとして扱われることになる。
まぁでもここまでは、それはそれでいいのかも知れない、とある程度納得できてしまうレベルの話なのかも知れない。フォーム部品もウィンドウの一種だと無理矢理納得することが、思考展開する上で圧倒的に不可能なことだとは思わない。でもそう思えるのは、これらは実行したときに、画面上で割と物体っぽく振る舞う概念だからなのではないか。
ちょっとしたゲームを作ろう、ということになって、その設計を考えたときに、そんなにたいそうなプログラムになるわけでもないし、ということで、実行時のシーンに応じてクラスを分けてみよう、と考えたとする。例えば以下の通りだ。
GameTitle
GamePlay
GameOver
名前を見ただけで、これらのクラスの「役割」は理解できると思う。GameTitle
クラスはゲームのタイトルを表示する。プログラム実行時に最初に呼び出されるシーンだ。GamePlay
クラスは実際にゲームを遊ぶプレイ中の制御処理を行う。タイトル表示シーンから特定のコントロール操作 (「start」ボタンを押す、等) により呼び出される。GameOver
クラスはゲームオーバーになったときに行われる動作だ。スコアを表示したり、ハイスコアランキングに登録したり、といった処理が考えられる。
そもそもこのような設計手法は妥当なのか? 現実問題としてこのプログラムを実行時のシーンに応じてモジュール分けすると言うことは十分考えられることなので、少なくとも手段のひとつとして絶対にあり得ないと言うことはないだろう。個人的にはこれはこれで十分アリだと思うが、実際の開発においてはチームで議論するなり、リーダーが自身のセンスに基づいて主導するなりすればよいことだ。閑話休題。
さて、これらのクラスの概要を書くとしたら、あなたはどんな風に説明するか? 「ゲームタイトルを表すクラス」? 「ゲームプレイを表すクラス」? 「ゲームオーバーを表すクラス」? どれもクラス名以上のことは書いていない。そろそろ、「○○を表すクラス」論法は無理が生じてきていると言えるのではないだろうか?
それよりも、「本クラスにおいて、」と前置きして (あるいはそう前置きされている物と仮定して)、「ゲームタイトルのアニメーション表示を実装する」、「ゲームプレイ中の中枢的な制御を実装する。具体的には以下の制御が対象となる: …」、「ゲームオーバーの処理を実装する。ハイスコアランキングの登録を含む」などと説明した方が、すっきりするだろう。
オブジェクト指向の「オブジェクト」とは、観念的に「物」や「物体」を表すことを指す、と考えるより、設計においてプログラムを個別の部品というかモジュールに分ける際に、そのモジュールが何を「目的」として実装されるのか、そのモジュールが「目的」としている「対象」は何なのか、をはっきりさせるための、プログラミング上での表現手法、と考えるべきだ。
生成されるインスタンスを観念的に「物」と言い表すことはできるかも知れないが、オブジェクト指向プログラミングにおいて重要なファクターは、必ずしもそこだけではないはずだ。「クラスもインスタンスも両者を含めてオブジェクトと言います」なんて説明で日本人プログラマーをはぐらかすのはもう止めよう。オブジェクト指向とは、プログラムを「目的」単位でモジュール化する手法である。その単位こそが (文字通り) クラスであり、従ってクラスの説明は実装の目的を記述することであるべきだ。
そのことを念頭に置き、そうした観念に頭が慣れるまでは、「オブジェクト指向」という語は封印し、代わりに日本語で潔く、「目的指向」と言い表すようにした方がよいのではないか、と提案する次第なのである。
最近のコメント