WEBVTT

00:00:00.480 --> 00:00:03.880 align:middle
こんにちは
今回の講義はとても高度なものです。

00:00:04.720 --> 00:00:08.040 align:middle
Pharo がどうやって

00:00:08.760 --> 00:00:11.840 align:middle
クラスとインスタンスの関係を
整理しているかを見ていきます。

00:00:12.400 --> 00:00:15.720 align:middle
これは本当に「好きな人」向けです。

00:00:16.520 --> 00:00:21.600 align:middle
習得することは必須ではありません。
実際、知らなくても Pharo を使っていますよね。

00:00:22.000 --> 00:00:26.200 align:middle
どうやって動いているのか知らなくても
Pharo でプログラムすることはできます。

00:00:26.400 --> 00:00:31.840 align:middle
しかし、それを講義で説明されなければ
不満な人もいることでしょう。

00:00:32.000 --> 00:00:34.640 align:middle
new がどこで定義されていて

00:00:34.800 --> 00:00:37.400 align:middle
メタクラスのクラスは何なのか
といったことです。

00:00:37.920 --> 00:00:40.840 align:middle
このビデオでは
そういったことを説明します。

00:00:41.040 --> 00:00:45.320 align:middle
すぐに理解できなくても問題ありません。

00:00:45.400 --> 00:00:47.920 align:middle
しかし、もし面白そうだと思ったら

00:00:48.680 --> 00:00:50.840 align:middle
何度も見返してみてください。

00:00:51.720 --> 00:00:54.320 align:middle
根源的なことが
そこに見つかるはずです。

00:00:54.760 --> 00:00:59.400 align:middle
このスライドで説明します。

00:00:59.680 --> 00:01:00.680 align:middle
この Mooc で何度も繰り返している

00:01:00.840 --> 00:01:04.080 align:middle
大事な概念です。

00:01:04.200 --> 00:01:09.360 align:middle
オブジェクトにメッセージを送ると

00:01:09.640 --> 00:01:13.560 align:middle
インスタンス関係のリンクを辿って
そのオブジェクトのクラスでメソッドを探索します。

00:01:13.760 --> 00:01:17.200 align:middle
もしそこになければ
継承を辿っていきます。

00:01:17.400 --> 00:01:21.920 align:middle
探索は常にクラスでスタートして
継承を辿っていきます。

00:01:22.400 --> 00:01:26.520 align:middle
このルールはシステマチックに適用されます。

00:01:26.920 --> 00:01:29.400 align:middle
メタクラスの説明は

00:01:29.600 --> 00:01:34.840 align:middle
7 つの簡潔なポイントに
まとめることができます。

00:01:35.760 --> 00:01:38.600 align:middle
あらゆるオブジェクトは
クラスのインスタンスです。

00:01:40.160 --> 00:01:43.080 align:middle
難しいですか？
この例を見てみましょう。

00:01:43.320 --> 00:01:47.200 align:middle
このオブジェクトは
OrderedCollection クラスのインスタンスです。

00:01:47.600 --> 00:01:49.160 align:middle
ここまではいいですね？

00:01:50.080 --> 00:01:55.200 align:middle
2 つ目のポイントです。あらゆるクラスは
Object クラスから継承しています。

00:01:57.080 --> 00:01:58.720 align:middle
ここにあるように

00:01:59.080 --> 00:02:03.840 align:middle
OrderedCollection などは
つまるところ Object から継承しています。

00:02:04.640 --> 00:02:07.040 align:middle
ここで言葉の補足ですが

00:02:07.200 --> 00:02:09.640 align:middle
eventually というのは
結局、つまるところ、ということです。

00:02:10.520 --> 00:02:11.560 align:middle
ややこしいですね。

00:02:11.800 --> 00:02:12.840 align:middle
つまり

00:02:13.400 --> 00:02:18.040 align:middle
継承関係のグラフは例外なく
Object に繋がっているのです。

00:02:20.080 --> 00:02:25.000 align:middle
Object の責任は何でしょう？
Object は全てのオブジェクトが共通して

00:02:25.200 --> 00:02:28.560 align:middle
持っている振る舞いを表します。
エラー処理や

00:02:28.720 --> 00:02:31.080 align:middle
halt（停止）や
announcement（通知）などです。

00:02:31.680 --> 00:02:34.760 align:middle
Object は継承の木の根です。

00:02:35.360 --> 00:02:38.520 align:middle
その責任は、最低限の振る舞いです。

00:02:39.800 --> 00:02:44.200 align:middle
リストに戻りましょう。
あらゆるクラスはメタクラスのインスタンスです。

00:02:45.800 --> 00:02:48.520 align:middle
以前のクラスでこれを説明しました。

00:02:49.080 --> 00:02:53.520 align:middle
クラス X は X class という名前の
メタクラスのインスタンスです。

00:02:53.680 --> 00:02:56.400 align:middle
OrderedCollection クラスは

00:02:56.560 --> 00:03:00.040 align:middle
OrderedCollection class クラスの
インスタンスです。

00:03:00.560 --> 00:03:05.040 align:middle
SequenceableCollection クラスも
同じ法則が成り立ちます。

00:03:05.560 --> 00:03:08.840 align:middle
Object クラスも
Object class クラスのインスタンスです。

00:03:09.080 --> 00:03:12.560 align:middle
全てのクラスは
名前の最後に「class」がくっついた

00:03:12.840 --> 00:03:16.280 align:middle
それぞれ別のメタクラスの
インスタンスです。

00:03:18.920 --> 00:03:20.640 align:middle
メタクラスはクラスを作った時に

00:03:20.840 --> 00:03:23.400 align:middle
自動的に作られます。

00:03:23.600 --> 00:03:28.320 align:middle
クラスを作る時にはメタクラスに
new メッセージを送っています。

00:03:30.080 --> 00:03:31.200 align:middle
次のポイントにいきます。

00:03:31.920 --> 00:03:35.400 align:middle
メタクラスの階層は
クラス階層と平行しています。

00:03:36.200 --> 00:03:39.160 align:middle
先ほど、OrderedCollection は

00:03:39.920 --> 00:03:43.200 align:middle
そのクラスのインスタンスだと
説明しました。

00:03:43.400 --> 00:03:46.400 align:middle
SequenceableCollection も
同様だと。

00:03:46.640 --> 00:03:51.080 align:middle
そこで
それら 2 つの関係を定める必要があります。

00:03:51.280 --> 00:03:56.040 align:middle
ここに継承関係がある以上は
こちらにもあるはずです。

00:03:56.920 --> 00:03:57.920 align:middle
どんな場合にも。

00:03:58.840 --> 00:04:03.400 align:middle
それが、2 つの平行した階層があると
いうことの意味です。

00:04:04.080 --> 00:04:06.320 align:middle
この階層はいつ使うのでしょう？

00:04:06.400 --> 00:04:10.080 align:middle
OrderedCollection に
new メッセージを送ると

00:04:10.520 --> 00:04:13.080 align:middle
どこから探索するでしょう？
OrderedCollection のクラスからです。

00:04:13.360 --> 00:04:18.920 align:middle
new が定義されているかどうかを
各クラスに尋ねていきます。

00:04:19.200 --> 00:04:23.080 align:middle
上にあがっていきながら
new が定義されているか尋ねていきます。

00:04:23.320 --> 00:04:28.400 align:middle
ここで最初に示したポイントを利用します。

00:04:28.840 --> 00:04:34.640 align:middle
メッセージを送ると
クラスから始めて継承を辿ります。

00:04:35.360 --> 00:04:37.400 align:middle
ここまでは

00:04:37.640 --> 00:04:41.400 align:middle
明快でしょう。
しかし、疑問が浮かび上がります。

00:04:41.600 --> 00:04:44.360 align:middle
Object class は
何のインスタンスでしょう？

00:04:45.200 --> 00:04:46.400 align:middle
悩むところです。

00:04:46.840 --> 00:04:50.200 align:middle
Object class の
スーパークラスは何でしょう？

00:04:51.000 --> 00:04:54.680 align:middle
メタクラスにメッセージを送っても
よいのでしょうか？

00:04:56.160 --> 00:04:59.400 align:middle
さらに、ここの何かしらに
メッセージを送るのは？

00:05:00.000 --> 00:05:01.600 align:middle
見てみましょう。

00:05:02.680 --> 00:05:07.800 align:middle
あらゆるメタクラスは
Class クラスから継承しています。

00:05:08.280 --> 00:05:10.080 align:middle
元は Behavior クラスです。

00:05:11.000 --> 00:05:14.680 align:middle
では最初の疑問に答えてみましょう。

00:05:14.840 --> 00:05:18.800 align:middle
Object class はクラスです。
Class から継承しています。

00:05:19.560 --> 00:05:23.320 align:middle
Class は ClassDescription や
Behavior から継承しています。

00:05:24.160 --> 00:05:28.040 align:middle
Pharo と違って
Lisp のような他のシステムでは

00:05:28.560 --> 00:05:31.200 align:middle
これら 2 つの要素は単体のクラスです。

00:05:31.680 --> 00:05:33.640 align:middle
Pharo では
再利用のために分割してあります。

00:05:33.840 --> 00:05:36.920 align:middle
Metaclass が ClassDescription
を継承して

00:05:37.080 --> 00:05:39.920 align:middle
ClassDescription を両方で
利用できるようにしています。

00:05:40.080 --> 00:05:44.400 align:middle
Behavior は
クラスの必須の部分を表現していて

00:05:44.600 --> 00:05:46.720 align:middle
Object から継承しています。

00:05:49.920 --> 00:05:53.000 align:middle
つまり、ここにメッセージを送ると

00:05:53.360 --> 00:05:56.040 align:middle
ずっとここまで辿ってきます。

00:05:57.280 --> 00:06:00.840 align:middle
クラスレベルの継承を辿ります。

00:06:03.080 --> 00:06:06.200 align:middle
では new がどこで定義されているのか？

00:06:06.840 --> 00:06:10.840 align:middle
インスタンスを生成する new メソッドは
Behavior で定義されています。

00:06:11.920 --> 00:06:17.680 align:middle
OrderedCollection に
new を送ると何が起こるのかというと

00:06:18.080 --> 00:06:20.400 align:middle
まず、そのクラスでメソッドを探索します。

00:06:21.080 --> 00:06:24.920 align:middle
new が継承の中で
再定義されていないとすると

00:06:25.080 --> 00:06:28.000 align:middle
スーパークラスを辿って探していきます。

00:06:28.360 --> 00:06:29.760 align:middle
new を見つけるまで。

00:06:29.920 --> 00:06:34.600 align:middle
メソッドを探索して
レシーバ上で実行します。

00:06:34.840 --> 00:06:39.000 align:middle
つまり、ここで new メソッドを見つけて
レシーバである

00:06:39.200 --> 00:06:44.200 align:middle
OrderedCollection クラスで実行します。
OrderedCollectionがインスタンスを生成します。

00:06:44.360 --> 00:06:46.840 align:middle
例えば 3 4 です。

00:06:47.720 --> 00:06:48.720 align:middle
いいですね？

00:06:49.400 --> 00:06:52.320 align:middle
今まで説明したポイントを使っています。

00:06:52.560 --> 00:06:57.840 align:middle
レシーバーのクラスから継承を辿って
探索していきます。

00:06:58.840 --> 00:07:01.920 align:middle
Behavior を一言で説明すると

00:07:02.160 --> 00:07:05.840 align:middle
インスタンスを持つオブジェクトの
エッセンスです。

00:07:06.800 --> 00:07:08.520 align:middle
インスタンスを持つオブジェクトは

00:07:09.760 --> 00:07:12.760 align:middle
スーパークラスへのリンクや
メソッド辞書や

00:07:13.000 --> 00:07:16.920 align:middle
インスタンスのフォーマットや
例に示したような

00:07:17.080 --> 00:07:22.840 align:middle
new や basicNew や new: などの
メソッドもです。持たなければなりません。

00:07:23.400 --> 00:07:26.520 align:middle
new と basicNew の違いは

00:07:26.680 --> 00:07:29.800 align:middle
basicNew は決して再定義してはならない
ということです。

00:07:30.080 --> 00:07:33.000 align:middle
メソッドについての講義で説明した通り

00:07:33.200 --> 00:07:38.760 align:middle
basic で始まるメソッドは
再定義しません。さもないと

00:07:39.600 --> 00:07:40.920 align:middle
元のメソッドに
アクセスできなくなってしまいます。

00:07:41.080 --> 00:07:46.320 align:middle
コンパイル済みメソッドにアクセスする方法は
ここに示す通り、他にも色々あります。

00:07:46.680 --> 00:07:49.080 align:middle
Behavior はクラスのエッセンスです。

00:07:50.280 --> 00:07:52.040 align:middle
ClassDescription は何でしょう？

00:07:52.400 --> 00:07:56.600 align:middle
Class と Metaclass に共有される
抽象クラスで

00:07:56.800 --> 00:07:59.800 align:middle
Behavior にいくつかの機能を加えます。

00:08:00.000 --> 00:08:04.920 align:middle
インスタンス変数の名前付けなどです。
Behavior までは人が関わらない実行でしたが

00:08:05.080 --> 00:08:07.520 align:middle
ClassDescription はそういう機能を
追加しています。

00:08:07.720 --> 00:08:13.080 align:middle
カテゴリーによる組織化というのは
ブラウザで表示するプロトコルです。

00:08:13.320 --> 00:08:17.680 align:middle
例えば、メソッドを printing プロトコルに
格納することができます。

00:08:18.200 --> 00:08:20.000 align:middle
また、名前に関することです。

00:08:20.200 --> 00:08:25.840 align:middle
チェンジセットの管理や
チェンジファイルの保存です。

00:08:26.280 --> 00:08:28.520 align:middle
自分で見てみてください。

00:08:28.760 --> 00:08:34.080 align:middle
このクラスは Class と Metaclass で
共有するためにあります。

00:08:35.000 --> 00:08:38.600 align:middle
Class の責任は

00:08:38.840 --> 00:08:42.080 align:middle
Pharo にあるクラスを表現することです。

00:08:42.320 --> 00:08:46.320 align:middle
クラス変数の表現や

00:08:46.600 --> 00:08:50.080 align:middle
名前付けやコンパイルを含みます。

00:08:50.560 --> 00:08:52.680 align:middle
もう一度言いますが
コードを読んでください。

00:08:54.400 --> 00:08:57.320 align:middle
クラスはメタクラスのインスタンスです。

00:08:57.560 --> 00:09:03.080 align:middle
Object は Object class という名の
クラスのインスタンスで

00:09:03.280 --> 00:09:06.400 align:middle
OrderedCollection についても同様で

00:09:06.680 --> 00:09:11.080 align:middle
Class や Class Description や
Behavior にも同様に適用されます。

00:09:11.680 --> 00:09:14.400 align:middle
したがって、Class は Class class
のインスタンスです。

00:09:14.600 --> 00:09:19.800 align:middle
そして ClassDescription は
ClassDescription class のインスタンスです。

00:09:20.400 --> 00:09:22.360 align:middle
Behavior も同様です。

00:09:22.560 --> 00:09:25.920 align:middle
継承も見ていく必要があります。

00:09:26.160 --> 00:09:30.840 align:middle
これら 2 つの間に
継承関係があるのならば

00:09:31.040 --> 00:09:34.440 align:middle
右側にも同じ関係があります。

00:09:34.720 --> 00:09:38.400 align:middle
ここを見てわかるように
継承を辿ることができます。

00:09:39.280 --> 00:09:43.760 align:middle
したがって、Behavior class は
Object class を継承します。

00:09:44.280 --> 00:09:46.400 align:middle
では、最後から 2 番目のポイントです。

00:09:46.760 --> 00:09:51.400 align:middle
あらゆるクラスはメタクラスのインスタンス
だとすると、疑問が 1 つ浮かび上がります。

00:09:52.360 --> 00:09:56.400 align:middle
OrderedCollection class は
何のインスタンスなのでしょう？

00:09:56.920 --> 00:09:59.600 align:middle
Pharo はすべてのものはオブジェクトなので

00:10:00.400 --> 00:10:04.720 align:middle
OrderedCollection class は
メタクラスのインスタンスです。

00:10:06.200 --> 00:10:10.320 align:middle
Object class と Class class は
メタクラスのインスタンスです。

00:10:10.600 --> 00:10:16.080 align:middle
システム中の全てのメタクラスは
Metaclass のインスタンスです。

00:10:17.400 --> 00:10:21.400 align:middle
さらに、Metaclass は
ClassDescription から継承しています。

00:10:21.600 --> 00:10:25.400 align:middle
インスタンスが 1 つしかない
特殊なクラスです。

00:10:26.000 --> 00:10:31.200 align:middle
そのインスタンスには名前がありません。
名前はそのまたインスタンスが定義します。

00:10:31.400 --> 00:10:33.200 align:middle
荒っぽいように見えるかもしれません。

00:10:33.640 --> 00:10:36.160 align:middle
そういうわけで
OrderedCollection は

00:10:36.400 --> 00:10:41.080 align:middle
OrderedCollection classのインスタンスで
名前が付けられています。

00:10:41.400 --> 00:10:44.840 align:middle
全てのメタクラスは Metaclass の
インスタンスです。

00:10:45.160 --> 00:10:49.720 align:middle
コードでのメタクラスの主な責任は

00:10:50.200 --> 00:10:55.720 align:middle
その唯一のインスタンスを
生成し初期化することです。

00:10:56.080 --> 00:10:59.920 align:middle
残された質問は 1 つです。

00:11:01.080 --> 00:11:04.400 align:middle
Metaclass は
何のインスタンスでしょう？

00:11:04.760 --> 00:11:10.640 align:middle
Metaclass は OrderedCollection 同様
クラスなので

00:11:11.000 --> 00:11:14.320 align:middle
Metaclass class というクラスの
インスタンスです。

00:11:14.920 --> 00:11:20.280 align:middle
Metaclass が ClassDescription から
継承していることはお分かりでしょう。

00:11:21.200 --> 00:11:26.080 align:middle
したがって Metaclass class は
ClassDescription class から継承します。

00:11:26.840 --> 00:11:30.840 align:middle
OrderedCollection が
Object から継承することから

00:11:31.000 --> 00:11:33.920 align:middle
OrderedCollection class は
Object class から継承するように。

00:11:34.080 --> 00:11:38.840 align:middle
Metaclass は
Metaclass class のインスタンスです。

00:11:39.280 --> 00:11:43.360 align:middle
OrderedCollection は
OrderedCollection class のインスタンスで

00:11:43.640 --> 00:11:48.280 align:middle
Metaclass class は
Metaclass のインスタンスです。

00:11:48.440 --> 00:11:55.200 align:middle
Class class や Object class が
Metaclass のインスタンスであるように。

00:11:55.640 --> 00:12:00.640 align:middle
このループは奇妙に見えるかもしれませんが
文脈がわかれば納得がいきます。

00:12:00.920 --> 00:12:06.400 align:middle
Pharo を使う上で必要な知識ではないので
スルーして結構です。

00:12:06.760 --> 00:12:08.680 align:middle
しかし、このグラフからわかるように

00:12:08.840 --> 00:12:12.200 align:middle
これまで話してきたポイントは
完璧に動作します。

00:12:12.400 --> 00:12:16.680 align:middle
オブジェクトにメッセージを送るたびに
そのオブジェクトのクラスを見て

00:12:16.840 --> 00:12:20.400 align:middle
継承の木を見ます。
これらの例に示された通りに。

00:12:20.760 --> 00:12:25.760 align:middle
このインスタンスにメッセージを送れば
Object に辿り着きます。

00:12:26.760 --> 00:12:29.920 align:middle
クラスにメッセージを送れば

00:12:30.840 --> 00:12:34.400 align:middle
メタクラスへ行って
継承を辿ります。

00:12:36.200 --> 00:12:40.600 align:middle
メタクラスにメッセージを送れば
どこを見ればいいでしょう？

00:12:41.560 --> 00:12:47.160 align:middle
Metaclass です。
メタクラスは Metaclass のインスタンスです。

00:12:47.560 --> 00:12:50.920 align:middle
インスタンス関係のリンクを辿ります。

00:12:51.600 --> 00:12:57.080 align:middle
これはメッセージが理解できない場合や
Object でのみメソッドが定義されている場合です。

00:12:57.600 --> 00:13:02.600 align:middle
では Metaclass にメッセージを送ると

00:13:02.840 --> 00:13:05.080 align:middle
どこを探索するでしょう？

00:13:05.400 --> 00:13:10.200 align:middle
まず Metaclass class から探して
そこから継承を辿ります。

00:13:11.400 --> 00:13:13.400 align:middle
それで、…おっと！

00:13:13.920 --> 00:13:17.520 align:middle
もっとややこしいことになります。

00:13:19.520 --> 00:13:23.680 align:middle
同様に、Metaclass class に
メッセージを送ると

00:13:23.840 --> 00:13:26.520 align:middle
あるいは OrderedCollection class に
メッセージを送ると

00:13:26.840 --> 00:13:29.160 align:middle
Metaclass class のクラス

00:13:30.080 --> 00:13:33.040 align:middle
つまり Metaclass を見ます。

00:13:33.200 --> 00:13:36.920 align:middle
OrderedCollection class の場合も同様に
この経路を辿ります。

00:13:37.200 --> 00:13:40.840 align:middle
このグラフは全体にわたって論理的である
ことがわかるでしょう。

00:13:41.560 --> 00:13:44.920 align:middle
グラフが不整合してはいけません。

00:13:45.360 --> 00:13:48.520 align:middle
仮想機械（VM）は1つのことしかしません。

00:13:48.680 --> 00:13:53.400 align:middle
クラスからメッセージを探して
継承を辿ります。

00:13:53.560 --> 00:13:58.360 align:middle
この普遍的なグラフはそのプロセスにおいて
一貫性を持っています。

00:13:59.040 --> 00:14:03.520 align:middle
これは本当にすごいことだと思います。
私自身、これを疑問に思っていました。

00:14:03.840 --> 00:14:08.280 align:middle
では、まとめると、クラスはオブジェクトで
メッセージを受け取ることができます。

00:14:08.600 --> 00:14:12.200 align:middle
手続きは全てのオブジェクトについて
同じものです。

00:14:12.400 --> 00:14:16.840 align:middle
メタクラスは
単一のインスタンスを持ち

00:14:17.040 --> 00:14:19.080 align:middle
明示的な名前を持っていません。

00:14:19.400 --> 00:14:22.080 align:middle
しかし、このことを知っていることは
必須ではありません。

