Lem さんによる、Morphic 奮闘記
このような場所ができてしまったので、つれづれなるままに書かかせて頂きます。
1.出会い
まず、僕の素性というか、Smalltalk や Squeak に関しての歴史を述べておきましょう。実をいうと。。。今年の4月にSqueak の存在を知り、Smalltalk については、その存在はきいたことあるけどまったく触ったことがないという人間です。だからSmalltalk歴2ヶ月弱。また、いかなる言語でもちゃんとしたプログラムは書いたことがないという
超初心者
コンピュータ入門の授業(いわゆるコンピュータ・リテラシィとかいうやつ)で何をやろうかと思案していたところでした。ワードやエクセルの使いかたを教えてもつまらんし、何よりもそんなの自分が興味がないので教えられない。Logoでもやろうか、でも最近オブジェクト指向とかが流行ってるしなあ。。。そんなところに教育用オブジェクト指向言語ドリトルの存在を知り、これはなかなかいいなあ、って思ってたらドリトルのメーリングリストでSqueakたらいうものの話題がちょっと出ていて、好奇心でダウンロード。動かすのはいいけど、何をやったらいいのかよくわからず、検索したらここのMorphicレッスンに当たりました。そして、
「こ、こ、これだ。僕が探し求めていたのはこれだ。しかもベースが憧れのSmalltalkだとお、(何も知らないくせに憧れだけはあった)そしたら、お絵かきツールで遊びながらプログラミングを学んで、飽きたらない人はちゃんとバックにSmalltalkが(!)待ってるじゃないか。噂ではSmalltalkは折り目正しいオブジェクト指向言語っていうじゃないか。これだこれだ」
と、噂でしか知らないSmalltalkに無責任に思い入れが強く、もう、頭はこれしかないという状態でちょっと興奮気味に、小学校のPTAの知りあいにふれまわっておりました。子供(小学3年生)にも見せるととても興味をそそられていい調子。そんな状態が数週間続いておりました。(あまりものを知らないので、こういうものに免疫がなかったんですね)
なお、この時点でのSqueakに対する認識は
・Smalltalkのシステムの上で実現された子供の教育用ソフト。
・タイルスクリプトはSmalltalkを子供に教えるための入門ツールに違いない。なぜなら、タイルスクリプトは上のチェックボックスでSmalltalkのコードに変えられるのだから。
・そしてこの教育用ソフトはMorphicと呼ばれているらしい。
・まてよそうするとSqueakって何のことだ?この教育用ソフトがSqueakなんじゃないのか?
・すごいことはすごいのが、たかが教育用ソフトをここまで持ち上げるということは何かものすごい秘密があるに違いない。それにしてもSqueakってなんだ?
2.Smalltalk入門
しばらくはタイルスクリプトで子供の描いた絵を動かしてゲームにしたり、ゴーカートを作って遊んだりしてたのですが、だんだん飽きてくる。
授業や、PTAなんかで紹介したいなあ、という思いの方が強くなってくる。そうなると、詳しく知らないとだめだなあ、と思い、インターネットで検索してまずSmalltalkの勉強をはじめる。
Smalltalkの勉強にはSqueakは勧められないという噂が飛び交っているので、しょうがないからVisualWorksをダウンロードして簡単なお勉強を。ただ、初心者用の話はだいたいどこも似たりよったりで、文法とか簡単な実行(do it,inspect it etc...)はなんとなくわかってくる。あくまでもなんとなく。
印象は、Smalltalkの文法ってのは超簡単。プログラムはクラスとメソッドを定義していくことが主体で、その様子はまるで数学のような作業だ。Smalltalkでプログラムを書くと抽象数学を実行するときの勘が掴める。
ただ、本格的なプログラムは書く気がないので、どうも先へ進まない。
意を決して初めてのインターネットでのお買い物をしてしまった。青木さんの「Smalltalkイディオム」を注文。3日後に届く。これでインターネットでの買いものの味をしめてしまった。(このとき、ついでにSQUEAK A Quick Trip To ObjectLand も注文する)
「Smalltalkイディオム」はとても面白い本。(今途中でとまってるけど)特にメタクラスの意味がこの本で演習して初めてわかった。Smalltalkが矛盾なくととのった概念体系を持っていることにえらく感動した。メタクラスのクラスのクラスとか、そういったものをinspectして遊んでいるうちに楽しくなってくる。
「おお、Smalltalkってなんでも見せてくれるぞ。すごいなあ」
この経験は後々、とても役にたった。初心者向けの記述にはこのメタクラスについて避けていたり、後回しにしたりしてるのが多いようだけど、僕の印象では、それがかえって本当の理解をさまたげているんじゃないかなあ、と感じた。こういうトリックめいたからくりはぜひとも初心者に楽しませて欲しいものです。
しばらくは、メタクラスとスーパークラスが、特にメタクラスが幽霊のように頭の中を回っているのでありました。
3.なんでモルフが動かないんだあ!!
よし。これでSmalltalkも分かったことだし(←甘いなあ)いよいよSqueakに挑戦だ。
「Squeakがすぐ飽きるのは、自分でモルフが作れないで、そこにある用意された部品だけを使わなければいけないからだ。」と勝手に思って(この時点ではまだSqueakが子供用のお絵かきツールだと思っている)
「それにはまずSmalltalkからモルフをコントロールする術を身に付ける必要がある。Smalltalkのことは分かったし、簡単なこっちゃ。モルフはオブジェクトなんだから、それに命令を送ればいいのだから」と楽観的な私。今から思えば、これが地獄の始まりであったのだ。
とりあえず、黄色の楕円モルフを動かしてみるか。というので、楕円モルフを取り出しておいてから、Workspace を意気揚揚とひらく。
「見てろよ。この楕円モルフにタイルスクリプトでさんざんやった
forward: 100
とか送ってやればいいんだから。これは、タイルスクリプトのときに、Smalltalkのコードを表示させて確認済みだから確かだ。では。。。???あれ?この黄色の楕円モルフは一体なんて名前なんだ?(正しくは楕円モルフの参照っていうのかな?)(!) そうかそうか、ハロを出したとき名前が Ellipse って出るなあ。これが名前か。よし。」
Ellipse forward:100
動け!(do it を実行する私)。。。何?
Unknown variable: Ellipse
だと?おいおいSqueak君よ。自分でEllipseとか出しといて「知らない」はないだろう。うーーん。まてよ。大文字で始まるのはクラスだよなあ。Ellipseってのはクラスの名前かも知れないぞ。それじゃこれでどうじゃあ。
ellipse forward:100
うわ、今度は真赤なウインドウで警告かよ。一体どうすりゃ名前がわかるんだ?それとも名前なんてないのか?
こうして、しょっぱなでつまずいたのであった。楕円モルフを目の前にして名前がわからないという不条理。名前さえわかれば動くのに。。。だがこれは地獄のほんの入り口に過ぎなかったのだ。
しばらく僕は黄色の楕円をみつめていた。名前、名前。この楕円を inspect できればわかるんだけど、それにはやっぱ名前がわからないとなあ。まてよ、赤ハロが使えないかな?メニューの中に inspect it っていうのがあるかもしれんぞ。
赤ハロをクリック。
ないなあ。メニューの上でマウスをスライドさせる。debug... の所でサブメニューがちらっと見えた。ちょっとまて。もう一度 debug... に合わせると
あった!!
inspect morph
地獄の門がギィーと音をたてて開きはじめた。
僕にはそんな音など耳に入るはずもなく、発見した喜びを噛み締めながらinspect morph をクリック。するとインスペクタ・ウインドウが開いた。タイトルは
an EllipseMorph<Ellipse>(2946)
やったあ。これで self のところを見れば正体がはっきりするぞ。というので self をクリックすると右のペインに
an EllipseMorph<Ellipse>(2946)
とでる。いやな予感。これがこの楕円モルフの名前か?この EllipseMorph っていうのは楕円モルフたちのクラスにちがいないけど、あとにくっついてる数字とかはなんだ?識別番号かな?そこで、もうひとつ楕円モルフを取り出して、同様にインスペクトすると、案の定番号がちがってる。そりゃそうだな。形が同じでも独立に動くのだから、識別番号みたいなのがないとな。しかし、これが名前だとは思えないぞ。だって、冠詞の an がついてるだけだし、名前にブランクとかあっていいのかよ。self だけじゃなく、他の変数の内容をみてもあまり参考になるようなものはない。しかたない。実行あるのみ。というので、Workspace の中で次々と以下のようなものを試していったのであった。(笑わないで)
an EllipseMorph<Ellipse>(2946) forwad:100
'an EllipseMorph<Ellipse>(2946)' forward:100
(ストリングにメッセージ送ってもなあ。だって空白が)
'an EllipseMorph<Ellipse>(2946)' asMorph forward:100
EllipseMorph new forwad:100
EllipseMorph new
(これ print it すると別の番号の楕円モルフができるみたいだけど、画面に出てこないぞ)
だ、だめだ。どうすりゃいいんだあっ!
おまけに最後のやつ、なんで画面に出て来ないんだ?
画面にパッと黄色い楕円が出てくるとこを想像していたんだけど。
生まれた楕円モルフはどこにいるんだ一体。
コンピュータのメモリーのどっかで生まれて日の目を見ずにそのまま死んでいくのか?
それじゃあまりに哀しい人生じゃないか。
だいたい、画面に出てくる黄色い楕円とは一体なんなんだ?
この黄色い楕円は「楕円モルフ」の「形」というひとつの側面に過ぎないってことか?
どんどん泥沼にはまっていくのであった。
4.解決、そして新たなる謎
僕はちょっとSqueakから離れることにした。こりゃあ想像以上に難物だ。しかたない、困ったときの「なんちゃってSqueak」(!)だ。というのでここのサイトから何か情報がえられないかと探してみる。すると興味を引かれる記事が
「Smalltalk、Squeak、Morphic、タイルスクリプティングの関係」
ここに何か糸口があるかも知れない。読んでみる。
「Smalltalk を通じて Morphic を理解する際に、Smalltalk と Self 双方の特徴とその差異を知らずにそれに当たるのはかなり難しいし、遠回りになると思います。」
と書いてある。Selfって知らないなあ。だけど難しいって書いてあるし、遠回りだって?意味がよくわからないけどなんかいやな気分だなあ。それにしてもheididorfさんの疑問は痛いほどよくわかるなあ。
「Smalltalk に関して書いてあることがちょっと…という場合は、失礼ながら Smalltalk への基本的理解が十分でない可能性がありますので、」
ほんと失礼だなあ(冗談)
「先にも述べたとおり、タイルスクリプティングで Smalltalk を学ぶのはかなり難しいと思います。」
そうかあ。以前、僕は誤解してたなあ。だけどオブジェクト指向っぽいコードの書き方はタイルスクリプティングで子供たちにも勘がつくんじゃないかなあ?しかしタイルスクリプティングでSmalltalkを学ぶのが難しいっていうのは、どういう意味で言ってるんだろう?まさか、言葉どおりのいみじゃないよなあ。言葉どおりの意味だとすると、あたりまえだと思うけどなあ。
「Morphic フレームワークを使って Smalltalk を学んでいる人は、世界的に見れば多いと思いますし可能だとは思います。ただ総じて、Morphic を含め、Squeak で Smalltalk を学ぶのはあまり薦められないというのが習熟した Smalltalker のコンセンサスのようです。」
だけど、VisualWorksで学んでるときは、謎もなくてあまり面白くなかったな。「Smalltalkイディオム」で謎が出てきて面白くなった。なんといってもこの謎だらけのSqueakだかMorphicだかで学んだほうが面白いんじゃないかなあ。「習熟したSmalltalker」ってなんだかえらそうだなあ。初心者に進化した差なんかわかるんかいな。(!) じゃあ、「習熟したSmalltalker」はどうやって学べって言ってるんだ?うーん考えてみれば、僕が今やってることは子供が玩具にあきて、その玩具を分解して中のぜんまいやら歯車やらを取り出して、わけもわからず動くしくみを理解しようとしてるのに似てるぞ。e-Toyってそういう意味だったりして。Smalltalkが面白いのは玩具の中身を見せてくれるからだな。
「はっは。たしかに怒りっぽい性格ですが…(^_^;)。」
うわ、sumimさんて怒りっぽいのか、気をつけないとな。
「「Smalltalk でいじる」というのは Smalltalk のコードから制御するという意味でしょうか? それなら Yes です。」
あ!!
「Workspace を開き、ウインドウメニューから「create textual references to dropped morphs」を選んでチェックをオンにします。そうした Workspace に制御したいスケッチモルフをドロップインすると、sketch2242 のようなテキストが現れるので、」
なんと!そんなしくみがあったのか。なんかずるいなあ。まあいいや、さっそくやってみよう。というので、再びSqueak発進。Workspaceを開いてメニューを見る。変だな「create textual refernces to dropped morphs」なんてないぞ。ああ、これのことかな?
「start accepting dropping morph for reference」
というのをメニューから選んでクリック。そして楕円モルフを取り出してWorkspaceの中へドロップイン!
ellipse3258
Workspace の中に僕があれほど探していた楕円モルフの名前が出てきたのだった。(!) なんだよ、この名前は、なあんのひねりもない。僕は惜しいところまでいってたじゃないか。まあ、いいや、あっけなく解決してしまったな。というのでWorkspaceに次のようにタイプする。
ellipse3258 forward:100
そして do it ! (これでようやく動くなあ、やれやれ)
MessageNotUnderstood: forward:
エラー?どういうことだ?forward のつづりが違ってるのか?
僕は確認するために楕円モルフの青ハロ(目玉のやつ)をクリックしてビューワを出し、「Ellipse forward by 5」と書いたタイルをデスクトップにドラッグ&ドロップ。スクリプトエディタに変身したやつの□をチェックすると
script1
self forward: 5
というのが出てくる。つづり間違ってないよなあ。変だなあ。この self ってのがこの楕円モルフのことだろ。だったらさっきので動くはずだけどなあ。ここに書いてあるのと同じこと書いてるんだから。楕円モルフのメソッドに forward: っていうのがあるんだよな。だってこれ basic っていうのに入ってたしなあ。どうやったら調べられるんだ?そうかそうか、システムブラウザで調べればいいんだ。ふっふっふ。なんか本格的になってきたぞ(とひとりで悦に入る私)
デスクトップメニューから open >> browser でブラウザを出す。
「うわー、いっぱいあるなあ。こういうときは右クリックするとなんとかなるもんなんだよね。クリックと。ほらね、ちゃんと find class... ってのがある。ここをクリックと。ええと探したいクラスは確か EllipseMorph だな。EllipseMorph と入れて Accept をクリック。おおー、出た出た。この --all-- というのはメソッドを全部出してるっていう意味だよね。この一番右に出てるのがメソッドだったよな。10個あるけど、あれ? forward: ってないなあ?おっかしいな。あっそうか、きっとスーパークラスで定義されてんだよ。だって前に進むのは楕円モルフだけじゃないし。俺って頭いいなあ(恥ずかしの自己陶酔)スーパークラスは、そうそうハイアラーキーブラウザってのがあるんだよね。EllipseMorph にマウスを合わせてまた右クリック。ほらあった browse hierarchy。これをクリックと。おおー、出た出た。EllipseMorph のスーパークラスは、へえー BorderedMorph っていうのか。こいつのメソッドを調べると。。。ないなあ。じゃあもうひとつ上のクラスの Morph ではどうだ?ないなあ。でも forwardDirection: っていうのがあるけど定義はどうも良くわからないことが書いてあるな。これは関係ないだろう。まさか Object にはないよな。でも念のため。。。やっぱないな。どうしたらわかるんだろう。なんだか意味がさっぱりわからなくなって来たぞ」
途方に暮れながら、なんとはなしに tools というフラップを引っ張り出して中を調べていると Method Finder(Selector Browser) というのが目に入る。
「ああこれか、これを使えばなんとかなりそうだ。これを引っ張りだしてと。けっこう小さいんだな。この左上の細いところに探したいメソッドの名前を入れればいいんだな。forward: と、そしてリターン。おお、下に何個か出てきたな。forward:っていうのを含んでるメソッドが出てくるわけか。forward: を選んでと、おっ、右に出てきたぞ」
NullEncoder forward:
Player forward:
StarSqueakTurtle forward:
「この三つだけか。モルフに関係ありそうなのはないなあ。ちゃんと動いてるのか?このSqueak バグがあるんじゃないの?(しろうとは自分がまちがってるとはなかなか認めない)」
しかたがないので Player forward: っていうのをクリックしてみる。するとシステムブラウザが開いて Player というクラスを見せてくれている。左から
Morphic-Scripting >> Player >> scripts-standard >> forward:
となっている。
「なんだこれは!?モルフにめちゃくちゃ関係ありそうじゃないか。どうなってるんだ?まてよ。あそこにあった、ほら、タイルスクリプトをSmalltalkのコードで表示したときのあの、selfだ。あれの正体は本当に楕円モルフなのか?僕はずっとあの self は楕円モルフだと思っていたけど本当にそうなのか?」
僕はあわてて楕円モルフの青ハロをクリック、タイルをデスクトップにドロップしてSmalltalkのコードに。self を選んで inspect it を実行。インスペクタウインドウが出る。タイトルは
Ellipse
なんだ、やっぱ楕円なのか。そして self を見てみると
a Player48(3445) named Ellipse
そして僕は途方にくれる。
5. a Player48 の謎
この Player48 というのはなんだろう?さっき forward: をメソッドにもつクラスを検索したら Player というのが出てきた。だけど Player48 というクラスはなかったぞ。というのでもう一度 method finder で forward: をもつクラスを検索するけどやっぱりない。しかし、Player48 というクラスは forward: というメソッドを受け付けることになってるわけだから、ええと...
そうか、Player のサブクラスなんだ。だから forward: を受け付けるにちがいない。というので Player に対して browse hierarchy をやるとあった、あった。 Player48 以外にも Player45、Player46、Player47 とかけっこうある。とまあ、そんなこんなで僕の能力を駆使して調べたところによると(駆使したわりにはあまりたいしたことはないのですが)
・Player48 は Player のサブクラスである。従って forward: というメソッドを受け付ける。
・Player48 は Morphic-UserObject というカテゴリ−に分類されている。
・Player48 は costume というインスタンス変数をもつ。
・Player48 のインスタンスであろう a Player48(3445) named Ellipse という長ったらしいオブジェクトの costume という変数には an EllipseMorph<ellipse>(3258) というのが入っている。
・そしてここが大切なのだが、このan EllipseMorph<ellipse>(3258) というのは、さっき出してきた楕円モルフ(ellipse3258)に他ならない。
・さらにこの楕円モルフ(ellipse3258)を inspect するとなんと extension という変数の中に player = a Player48(3445)named ellipse と書かれた部分がある。(さっきこんなのあったかなあ?)
以上のことから次のことがおそまつながら推理されるのであった。
・どうも楕円モルフとPlayer というのは密接に結びついているらしい。
・Playerというのは俳優ってことか?だって costume って衣装ってことだろ。
・Player48 のインスタンスとは、楕円モルフという衣装をまとった俳優(player)ということか。
・Player48 以外にも数字がちがうのがいっぱいあり、また、カテゴリーが Morphic-UserObject ってなってることから、Player48 というのは楕円モルフができたときに自動生成されるクラスじゃないだろうか。
しっかし、なんでこんなめんどくさい仕組みにする必要があるんだ?
僕は上の推理を実験で確かめようと思い、別の楕円モルフをもうひとつ取り出してインスペクトして extension という変数を見てみた。ところが player などというのがそこにはない。さっきの楕円モルフにはあったのに。ところが、なんのきなしに新しい楕円モルフを持ち上げたときである。すると!extension の中が変化したのだ。わけのわからない文字がだらだらと出る。モルフを下に置くともとにもどる。なるほど!!この extension の中身はアクションを起すとかなり変化するわけだ。そうすると、スクリプトを書くことによって変化するかも!ってんで青ハロをクリックして Viewer を出したら案の定 extension の中身に
[player = an UnscriptedPlayer (3631) named Ellipse1]
というのが出てきたのだった。さらに Viewer からタイルを取り出してスクリプトを書こうとしたら、また extension の中身が変化して
[player = a Player49 (3631) named Ellipse1]
となる。やっぱりそうか。タイルスクリプトをしようとすることで新しいクラス Player49 ってのが自動的に生成されたんだ。
さらに面白いことは SystemBrowser で Player49 を出したまま、スクリプトを作るとリアルタイムで Player49 のメソッドが script1, script2 という風に追加されていくことだ。つまりタイルスクリプティングすることで Playrer49 のメソッドが次々に定義されて追加されるしくみになっているのだ。
楕円モルフそれぞれに対して PlayrerXX というクラスが生成され、それが forward: 100 などのメッセージを、楕円モルフの変わりに受け付けている。またタイルスクリプティングで作ったものは PlayerXX というクラスのメソッドとして追加されていくのだ。僕はこの仕組みを発見して興奮した。そうすると、この a Player49 に forward: 100 というのを送ってやれば(からくりはいまいちわからないけど)a Player49 が楕円モルフを動かしてくれるのではないだろうか。
しかし僕は Workspace でそれをやろうとして、また考え込んでしまった。
a Player49 とかいうオブジェクトはどうやって捕まえたらいいんだ?
楕円モルフはそこに姿があったのでそれを Workspace にドロップインすることで(仮の)名前が出せた。この a Player49 というオブジェクトは姿なんかないからそんなことできないぞ。またもや、どうすりゃいいのさ思案橋。
6. ついに楕円モルフが動いたぞ!
この辺から僕はそうとういいかげんになってきている。そろそろ疲れが見え始めたのだ。だがそのいいかげんさが功を奏した。僕の中では次のような推理がかなりいいかげんにめぐったのであった。
・a Player49 というのは対応する楕円モルフの extension という変数の中の player という変数らしきものにしまわれている。
・ところで Smalltalk では、変数の中身を欲しいときは変数と同じメソッドを使うならわしとなっている。
・player というのは楕円モルフが直接持っている変数ではないが、楕円モルフ固有の変数には違いないから、楕円モルフに player というメッセージを送れば自分の player を返してくれるのではないだろうか?
そこで Method Finder で player を検索するとやっぱり Morph というクラスが player というメソッドを持っていることを発見。中身も僕の推理が満足のいく次のようなものであった。
player
extension
ifNil: [^ nil].
^ extension player
この位の行のプログラムならなんとか読める。僕は確信を持った。楕円モルフの名前(ellipse3419)を Workspce に出しておき、 次のように入力して do it !!
ellipse3419 player forward: 100.
すると、ついに
楕円モルフが前に進んだ!!!
僕は感動した。あれだけウンともスンとも言わなかった楕円モルフが動いたのだ。一体この楕円モルフを前に少し動かすのに何時間かかっただろうか?だが、今は動く。回転だってさせられる。その気になれば複雑な動きだってすぐできるようになるだろう。しばらく僕は楕円モルフをねじ伏せた感動に酔っていた。
が、しかしその感動も収まるとともに、自分がほとんど何ひとつわかってないじゃないか、という気持ちにとらわれ始めたのだ。それは以前感じたある疑問が再び頭をもたげ始めたからであった。その疑問とは
しっかし、なんでこんなめんどくさい仕組みにする必要があるんだ?
というものであった。
7.Self の謎
こうなったら勇気をだして、怒りっぽい性格のsumimさんに尋ねるしかなかろうというので、僕は失礼のないように気をつけながら、ついにheididorfさんの場所に投稿したのであった。そもそも僕がこのMorphicの底なし沼にはまってしまったのは、sumimさんがあっさりとsketch morphをワークスペースの中から動かしていたのが原因なのであった。まあ、今から考えるとモルフを「前進させる」という作業は、モルフの「位置を変える」というのに比べるとそうとうに複雑な作業なのであった。なぜならモルフがどっちの方向を向いているかによって前進する方向が違ってくるので単純に位置の座標を変えるというのとはかなり違うのだ。だけど、最初は簡単なことだと思っていたのがそもそもの間違いであった。そういうわけで、僕は今までのいきさつをかいつまんで投稿し、楕円モルフとPlayer というクラスの関係がいまいちわからない、という趣旨のことを書いたのであった。それに対するsumimさんの答えは非常に好奇心をそそるものであったが最初、それは僕の理解を超えるものであった。
「生まれた瞬間に、歩き方や餌の取り方を知っている(実際はその都度、親に尋ねるわけですが) Smalltalk のインスタンスと違い、Self のオブジェクトはまっさらな状態で生まれて来るので、自分で生きてゆくためにはどうしたらよいか(オブジェクトとしてどうアイデンティティを確立するか、どうやって役立ってゆくか)を後から学ばなければいけません。反面、生みの親(クラス)に束縛され、その教えを忠実に実行することしかできないインスタンスに対し、Self のオブジェクトは、誰からも束縛されない自由を持っています。」
今読むと、ほんとうにすばらしい解説であるのだが、そもそもSelfなる処理系を一度も聞いたことのない僕には、やたら好奇心だけはかきたてられるが、よく理解できないのであった。そういうわけなので、またまたこのSelfなるものの謎が増えてしまったのだ(とほほ)。
(あきれるかもしれないけど、まだつづく)(!)
このページを編集 (22984 bytes)
|
以下の 3 ページから参照されています。 |
This page has been visited 5373 times.