1 00:00:00,480 --> 00:00:03,880 こんにちは 今回の講義はとても高度なものです。 2 00:00:04,720 --> 00:00:08,040 Pharo がどうやって 3 00:00:08,760 --> 00:00:11,840 クラスとインスタンスの関係を 整理しているかを見ていきます。 4 00:00:12,400 --> 00:00:15,720 これは本当に「好きな人」向けです。 5 00:00:16,520 --> 00:00:21,600 習得することは必須ではありません。 実際、知らなくても Pharo を使っていますよね。 6 00:00:22,000 --> 00:00:26,200 どうやって動いているのか知らなくても Pharo でプログラムすることはできます。 7 00:00:26,400 --> 00:00:31,840 しかし、それを講義で説明されなければ 不満な人もいることでしょう。 8 00:00:32,000 --> 00:00:34,640 new がどこで定義されていて 9 00:00:34,800 --> 00:00:37,400 メタクラスのクラスは何なのか といったことです。 10 00:00:37,920 --> 00:00:40,840 このビデオでは そういったことを説明します。 11 00:00:41,040 --> 00:00:45,320 すぐに理解できなくても問題ありません。 12 00:00:45,400 --> 00:00:47,920 しかし、もし面白そうだと思ったら 13 00:00:48,680 --> 00:00:50,840 何度も見返してみてください。 14 00:00:51,720 --> 00:00:54,320 根源的なことが そこに見つかるはずです。 15 00:00:54,760 --> 00:00:59,400 このスライドで説明します。 16 00:00:59,680 --> 00:01:00,680 この Mooc で何度も繰り返している 17 00:01:00,840 --> 00:01:04,080 大事な概念です。 18 00:01:04,200 --> 00:01:09,360 オブジェクトにメッセージを送ると 19 00:01:09,640 --> 00:01:13,560 インスタンス関係のリンクを辿って そのオブジェクトのクラスでメソッドを探索します。 20 00:01:13,760 --> 00:01:17,200 もしそこになければ 継承を辿っていきます。 21 00:01:17,400 --> 00:01:21,920 探索は常にクラスでスタートして 継承を辿っていきます。 22 00:01:22,400 --> 00:01:26,520 このルールはシステマチックに適用されます。 23 00:01:26,920 --> 00:01:29,400 メタクラスの説明は 24 00:01:29,600 --> 00:01:34,840 7 つの簡潔なポイントに まとめることができます。 25 00:01:35,760 --> 00:01:38,600 あらゆるオブジェクトは クラスのインスタンスです。 26 00:01:40,160 --> 00:01:43,080 難しいですか? この例を見てみましょう。 27 00:01:43,320 --> 00:01:47,200 このオブジェクトは OrderedCollection クラスのインスタンスです。 28 00:01:47,600 --> 00:01:49,160 ここまではいいですね? 29 00:01:50,080 --> 00:01:55,200 2 つ目のポイントです。あらゆるクラスは Object クラスから継承しています。 30 00:01:57,080 --> 00:01:58,720 ここにあるように 31 00:01:59,080 --> 00:02:03,840 OrderedCollection などは つまるところ Object から継承しています。 32 00:02:04,640 --> 00:02:07,040 ここで言葉の補足ですが 33 00:02:07,200 --> 00:02:09,640 eventually というのは 結局、つまるところ、ということです。 34 00:02:10,520 --> 00:02:11,560 ややこしいですね。 35 00:02:11,800 --> 00:02:12,840 つまり 36 00:02:13,400 --> 00:02:18,040 継承関係のグラフは例外なく Object に繋がっているのです。 37 00:02:20,080 --> 00:02:25,000 Object の責任は何でしょう? Object は全てのオブジェクトが共通して 38 00:02:25,200 --> 00:02:28,560 持っている振る舞いを表します。 エラー処理や 39 00:02:28,720 --> 00:02:31,080 halt(停止)や announcement(通知)などです。 40 00:02:31,680 --> 00:02:34,760 Object は継承の木の根です。 41 00:02:35,360 --> 00:02:38,520 その責任は、最低限の振る舞いです。 42 00:02:39,800 --> 00:02:44,200 リストに戻りましょう。 あらゆるクラスはメタクラスのインスタンスです。 43 00:02:45,800 --> 00:02:48,520 以前のクラスでこれを説明しました。 44 00:02:49,080 --> 00:02:53,520 クラス X は X class という名前の メタクラスのインスタンスです。 45 00:02:53,680 --> 00:02:56,400 OrderedCollection クラスは 46 00:02:56,560 --> 00:03:00,040 OrderedCollection class クラスの インスタンスです。 47 00:03:00,560 --> 00:03:05,040 SequenceableCollection クラスも 同じ法則が成り立ちます。 48 00:03:05,560 --> 00:03:08,840 Object クラスも Object class クラスのインスタンスです。 49 00:03:09,080 --> 00:03:12,560 全てのクラスは 名前の最後に「class」がくっついた 50 00:03:12,840 --> 00:03:16,280 それぞれ別のメタクラスの インスタンスです。 51 00:03:18,920 --> 00:03:20,640 メタクラスはクラスを作った時に 52 00:03:20,840 --> 00:03:23,400 自動的に作られます。 53 00:03:23,600 --> 00:03:28,320 クラスを作る時にはメタクラスに new メッセージを送っています。 54 00:03:30,080 --> 00:03:31,200 次のポイントにいきます。 55 00:03:31,920 --> 00:03:35,400 メタクラスの階層は クラス階層と平行しています。 56 00:03:36,200 --> 00:03:39,160 先ほど、OrderedCollection は 57 00:03:39,920 --> 00:03:43,200 そのクラスのインスタンスだと 説明しました。 58 00:03:43,400 --> 00:03:46,400 SequenceableCollection も 同様だと。 59 00:03:46,640 --> 00:03:51,080 そこで それら 2 つの関係を定める必要があります。 60 00:03:51,280 --> 00:03:56,040 ここに継承関係がある以上は こちらにもあるはずです。 61 00:03:56,920 --> 00:03:57,920 どんな場合にも。 62 00:03:58,840 --> 00:04:03,400 それが、2 つの平行した階層があると いうことの意味です。 63 00:04:04,080 --> 00:04:06,320 この階層はいつ使うのでしょう? 64 00:04:06,400 --> 00:04:10,080 OrderedCollection に new メッセージを送ると 65 00:04:10,520 --> 00:04:13,080 どこから探索するでしょう? OrderedCollection のクラスからです。 66 00:04:13,360 --> 00:04:18,920 new が定義されているかどうかを 各クラスに尋ねていきます。 67 00:04:19,200 --> 00:04:23,080 上にあがっていきながら new が定義されているか尋ねていきます。 68 00:04:23,320 --> 00:04:28,400 ここで最初に示したポイントを利用します。 69 00:04:28,840 --> 00:04:34,640 メッセージを送ると クラスから始めて継承を辿ります。 70 00:04:35,360 --> 00:04:37,400 ここまでは 71 00:04:37,640 --> 00:04:41,400 明快でしょう。 しかし、疑問が浮かび上がります。 72 00:04:41,600 --> 00:04:44,360 Object class は 何のインスタンスでしょう? 73 00:04:45,200 --> 00:04:46,400 悩むところです。 74 00:04:46,840 --> 00:04:50,200 Object class の スーパークラスは何でしょう? 75 00:04:51,000 --> 00:04:54,680 メタクラスにメッセージを送っても よいのでしょうか? 76 00:04:56,160 --> 00:04:59,400 さらに、ここの何かしらに メッセージを送るのは? 77 00:05:00,000 --> 00:05:01,600 見てみましょう。 78 00:05:02,680 --> 00:05:07,800 あらゆるメタクラスは Class クラスから継承しています。 79 00:05:08,280 --> 00:05:10,080 元は Behavior クラスです。 80 00:05:11,000 --> 00:05:14,680 では最初の疑問に答えてみましょう。 81 00:05:14,840 --> 00:05:18,800 Object class はクラスです。 Class から継承しています。 82 00:05:19,560 --> 00:05:23,320 Class は ClassDescription や Behavior から継承しています。 83 00:05:24,160 --> 00:05:28,040 Pharo と違って Lisp のような他のシステムでは 84 00:05:28,560 --> 00:05:31,200 これら 2 つの要素は単体のクラスです。 85 00:05:31,680 --> 00:05:33,640 Pharo では 再利用のために分割してあります。 86 00:05:33,840 --> 00:05:36,920 Metaclass が ClassDescription を継承して 87 00:05:37,080 --> 00:05:39,920 ClassDescription を両方で 利用できるようにしています。 88 00:05:40,080 --> 00:05:44,400 Behavior は クラスの必須の部分を表現していて 89 00:05:44,600 --> 00:05:46,720 Object から継承しています。 90 00:05:49,920 --> 00:05:53,000 つまり、ここにメッセージを送ると 91 00:05:53,360 --> 00:05:56,040 ずっとここまで辿ってきます。 92 00:05:57,280 --> 00:06:00,840 クラスレベルの継承を辿ります。 93 00:06:03,080 --> 00:06:06,200 では new がどこで定義されているのか? 94 00:06:06,840 --> 00:06:10,840 インスタンスを生成する new メソッドは Behavior で定義されています。 95 00:06:11,920 --> 00:06:17,680 OrderedCollection に new を送ると何が起こるのかというと 96 00:06:18,080 --> 00:06:20,400 まず、そのクラスでメソッドを探索します。 97 00:06:21,080 --> 00:06:24,920 new が継承の中で 再定義されていないとすると 98 00:06:25,080 --> 00:06:28,000 スーパークラスを辿って探していきます。 99 00:06:28,360 --> 00:06:29,760 new を見つけるまで。 100 00:06:29,920 --> 00:06:34,600 メソッドを探索して レシーバ上で実行します。 101 00:06:34,840 --> 00:06:39,000 つまり、ここで new メソッドを見つけて レシーバである 102 00:06:39,200 --> 00:06:44,200 OrderedCollection クラスで実行します。 OrderedCollectionがインスタンスを生成します。 103 00:06:44,360 --> 00:06:46,840 例えば 3 4 です。 104 00:06:47,720 --> 00:06:48,720 いいですね? 105 00:06:49,400 --> 00:06:52,320 今まで説明したポイントを使っています。 106 00:06:52,560 --> 00:06:57,840 レシーバーのクラスから継承を辿って 探索していきます。 107 00:06:58,840 --> 00:07:01,920 Behavior を一言で説明すると 108 00:07:02,160 --> 00:07:05,840 インスタンスを持つオブジェクトの エッセンスです。 109 00:07:06,800 --> 00:07:08,520 インスタンスを持つオブジェクトは 110 00:07:09,760 --> 00:07:12,760 スーパークラスへのリンクや メソッド辞書や 111 00:07:13,000 --> 00:07:16,920 インスタンスのフォーマットや 例に示したような 112 00:07:17,080 --> 00:07:22,840 new や basicNew や new: などの メソッドもです。持たなければなりません。 113 00:07:23,400 --> 00:07:26,520 new と basicNew の違いは 114 00:07:26,680 --> 00:07:29,800 basicNew は決して再定義してはならない ということです。 115 00:07:30,080 --> 00:07:33,000 メソッドについての講義で説明した通り 116 00:07:33,200 --> 00:07:38,760 basic で始まるメソッドは 再定義しません。さもないと 117 00:07:39,600 --> 00:07:40,920 元のメソッドに アクセスできなくなってしまいます。 118 00:07:41,080 --> 00:07:46,320 コンパイル済みメソッドにアクセスする方法は ここに示す通り、他にも色々あります。 119 00:07:46,680 --> 00:07:49,080 Behavior はクラスのエッセンスです。 120 00:07:50,280 --> 00:07:52,040 ClassDescription は何でしょう? 121 00:07:52,400 --> 00:07:56,600 Class と Metaclass に共有される 抽象クラスで 122 00:07:56,800 --> 00:07:59,800 Behavior にいくつかの機能を加えます。 123 00:08:00,000 --> 00:08:04,920 インスタンス変数の名前付けなどです。 Behavior までは人が関わらない実行でしたが 124 00:08:05,080 --> 00:08:07,520 ClassDescription はそういう機能を 追加しています。 125 00:08:07,720 --> 00:08:13,080 カテゴリーによる組織化というのは ブラウザで表示するプロトコルです。 126 00:08:13,320 --> 00:08:17,680 例えば、メソッドを printing プロトコルに 格納することができます。 127 00:08:18,200 --> 00:08:20,000 また、名前に関することです。 128 00:08:20,200 --> 00:08:25,840 チェンジセットの管理や チェンジファイルの保存です。 129 00:08:26,280 --> 00:08:28,520 自分で見てみてください。 130 00:08:28,760 --> 00:08:34,080 このクラスは Class と Metaclass で 共有するためにあります。 131 00:08:35,000 --> 00:08:38,600 Class の責任は 132 00:08:38,840 --> 00:08:42,080 Pharo にあるクラスを表現することです。 133 00:08:42,320 --> 00:08:46,320 クラス変数の表現や 134 00:08:46,600 --> 00:08:50,080 名前付けやコンパイルを含みます。 135 00:08:50,560 --> 00:08:52,680 もう一度言いますが コードを読んでください。 136 00:08:54,400 --> 00:08:57,320 クラスはメタクラスのインスタンスです。 137 00:08:57,560 --> 00:09:03,080 Object は Object class という名の クラスのインスタンスで 138 00:09:03,280 --> 00:09:06,400 OrderedCollection についても同様で 139 00:09:06,680 --> 00:09:11,080 Class や Class Description や Behavior にも同様に適用されます。 140 00:09:11,680 --> 00:09:14,400 したがって、Class は Class class のインスタンスです。 141 00:09:14,600 --> 00:09:19,800 そして ClassDescription は ClassDescription class のインスタンスです。 142 00:09:20,400 --> 00:09:22,360 Behavior も同様です。 143 00:09:22,560 --> 00:09:25,920 継承も見ていく必要があります。 144 00:09:26,160 --> 00:09:30,840 これら 2 つの間に 継承関係があるのならば 145 00:09:31,040 --> 00:09:34,440 右側にも同じ関係があります。 146 00:09:34,720 --> 00:09:38,400 ここを見てわかるように 継承を辿ることができます。 147 00:09:39,280 --> 00:09:43,760 したがって、Behavior class は Object class を継承します。 148 00:09:44,280 --> 00:09:46,400 では、最後から 2 番目のポイントです。 149 00:09:46,760 --> 00:09:51,400 あらゆるクラスはメタクラスのインスタンス だとすると、疑問が 1 つ浮かび上がります。 150 00:09:52,360 --> 00:09:56,400 OrderedCollection class は 何のインスタンスなのでしょう? 151 00:09:56,920 --> 00:09:59,600 Pharo はすべてのものはオブジェクトなので 152 00:10:00,400 --> 00:10:04,720 OrderedCollection class は メタクラスのインスタンスです。 153 00:10:06,200 --> 00:10:10,320 Object class と Class class は メタクラスのインスタンスです。 154 00:10:10,600 --> 00:10:16,080 システム中の全てのメタクラスは Metaclass のインスタンスです。 155 00:10:17,400 --> 00:10:21,400 さらに、Metaclass は ClassDescription から継承しています。 156 00:10:21,600 --> 00:10:25,400 インスタンスが 1 つしかない 特殊なクラスです。 157 00:10:26,000 --> 00:10:31,200 そのインスタンスには名前がありません。 名前はそのまたインスタンスが定義します。 158 00:10:31,400 --> 00:10:33,200 荒っぽいように見えるかもしれません。 159 00:10:33,640 --> 00:10:36,160 そういうわけで OrderedCollection は 160 00:10:36,400 --> 00:10:41,080 OrderedCollection classのインスタンスで 名前が付けられています。 161 00:10:41,400 --> 00:10:44,840 全てのメタクラスは Metaclass の インスタンスです。 162 00:10:45,160 --> 00:10:49,720 コードでのメタクラスの主な責任は 163 00:10:50,200 --> 00:10:55,720 その唯一のインスタンスを 生成し初期化することです。 164 00:10:56,080 --> 00:10:59,920 残された質問は 1 つです。 165 00:11:01,080 --> 00:11:04,400 Metaclass は 何のインスタンスでしょう? 166 00:11:04,760 --> 00:11:10,640 Metaclass は OrderedCollection 同様 クラスなので 167 00:11:11,000 --> 00:11:14,320 Metaclass class というクラスの インスタンスです。 168 00:11:14,920 --> 00:11:20,280 Metaclass が ClassDescription から 継承していることはお分かりでしょう。 169 00:11:21,200 --> 00:11:26,080 したがって Metaclass class は ClassDescription class から継承します。 170 00:11:26,840 --> 00:11:30,840 OrderedCollection が Object から継承することから 171 00:11:31,000 --> 00:11:33,920 OrderedCollection class は Object class から継承するように。 172 00:11:34,080 --> 00:11:38,840 Metaclass は Metaclass class のインスタンスです。 173 00:11:39,280 --> 00:11:43,360 OrderedCollection は OrderedCollection class のインスタンスで 174 00:11:43,640 --> 00:11:48,280 Metaclass class は Metaclass のインスタンスです。 175 00:11:48,440 --> 00:11:55,200 Class class や Object class が Metaclass のインスタンスであるように。 176 00:11:55,640 --> 00:12:00,640 このループは奇妙に見えるかもしれませんが 文脈がわかれば納得がいきます。 177 00:12:00,920 --> 00:12:06,400 Pharo を使う上で必要な知識ではないので スルーして結構です。 178 00:12:06,760 --> 00:12:08,680 しかし、このグラフからわかるように 179 00:12:08,840 --> 00:12:12,200 これまで話してきたポイントは 完璧に動作します。 180 00:12:12,400 --> 00:12:16,680 オブジェクトにメッセージを送るたびに そのオブジェクトのクラスを見て 181 00:12:16,840 --> 00:12:20,400 継承の木を見ます。 これらの例に示された通りに。 182 00:12:20,760 --> 00:12:25,760 このインスタンスにメッセージを送れば Object に辿り着きます。 183 00:12:26,760 --> 00:12:29,920 クラスにメッセージを送れば 184 00:12:30,840 --> 00:12:34,400 メタクラスへ行って 継承を辿ります。 185 00:12:36,200 --> 00:12:40,600 メタクラスにメッセージを送れば どこを見ればいいでしょう? 186 00:12:41,560 --> 00:12:47,160 Metaclass です。 メタクラスは Metaclass のインスタンスです。 187 00:12:47,560 --> 00:12:50,920 インスタンス関係のリンクを辿ります。 188 00:12:51,600 --> 00:12:57,080 これはメッセージが理解できない場合や Object でのみメソッドが定義されている場合です。 189 00:12:57,600 --> 00:13:02,600 では Metaclass にメッセージを送ると 190 00:13:02,840 --> 00:13:05,080 どこを探索するでしょう? 191 00:13:05,400 --> 00:13:10,200 まず Metaclass class から探して そこから継承を辿ります。 192 00:13:11,400 --> 00:13:13,400 それで、…おっと! 193 00:13:13,920 --> 00:13:17,520 もっとややこしいことになります。 194 00:13:19,520 --> 00:13:23,680 同様に、Metaclass class に メッセージを送ると 195 00:13:23,840 --> 00:13:26,520 あるいは OrderedCollection class に メッセージを送ると 196 00:13:26,840 --> 00:13:29,160 Metaclass class のクラス 197 00:13:30,080 --> 00:13:33,040 つまり Metaclass を見ます。 198 00:13:33,200 --> 00:13:36,920 OrderedCollection class の場合も同様に この経路を辿ります。 199 00:13:37,200 --> 00:13:40,840 このグラフは全体にわたって論理的である ことがわかるでしょう。 200 00:13:41,560 --> 00:13:44,920 グラフが不整合してはいけません。 201 00:13:45,360 --> 00:13:48,520 仮想機械(VM)は1つのことしかしません。 202 00:13:48,680 --> 00:13:53,400 クラスからメッセージを探して 継承を辿ります。 203 00:13:53,560 --> 00:13:58,360 この普遍的なグラフはそのプロセスにおいて 一貫性を持っています。 204 00:13:59,040 --> 00:14:03,520 これは本当にすごいことだと思います。 私自身、これを疑問に思っていました。 205 00:14:03,840 --> 00:14:08,280 では、まとめると、クラスはオブジェクトで メッセージを受け取ることができます。 206 00:14:08,600 --> 00:14:12,200 手続きは全てのオブジェクトについて 同じものです。 207 00:14:12,400 --> 00:14:16,840 メタクラスは 単一のインスタンスを持ち 208 00:14:17,040 --> 00:14:19,080 明示的な名前を持っていません。 209 00:14:19,400 --> 00:14:22,080 しかし、このことを知っていることは 必須ではありません。