﻿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
しかし、このことを知っていることは
必須ではありません。
