1
00:00:01,910 --> 00:00:04,410
このビデオは本MOOCでの反復です。

2
00:00:04,577 --> 00:00:07,030
ここでの反復というのは
自分でやってみることです。

3
00:00:07,520 --> 00:00:09,540
ビデオを見て見たものを
1つ1つ実行することです。

4
00:00:10,060 --> 00:00:13,470
我々がプログラムする方法を見ることを
お勧めする意味もあります。

5
00:00:13,720 --> 00:00:17,680
台本通りに忠実には進まないかもしれませんが

6
00:00:17,847 --> 00:00:20,060
できるだけ、そうしましょう。
しかしバグを見つけたり

7
00:00:20,227 --> 00:00:23,090
そんなことがあったら
その都度対処しましょう。

8
00:00:24,870 --> 00:00:29,130
このビデオでは
簡単な言語をプログラムします。

9
00:00:29,297 --> 00:00:32,040
ロールプレイングゲームにあるような
感じの言語です。

10
00:00:32,207 --> 00:00:35,930
ダンジョンズ＆ドラゴンズのような。
例えば

11
00:00:36,097 --> 00:00:38,800
この記述を手にした人は

12
00:00:38,967 --> 00:00:40,010
どういう風に読み取ったらいいのでしょう？

13
00:00:40,420 --> 00:00:45,380
こういう意味です。
2つの20面ダイスと1つの4面ダイスを振りなさい。

14
00:00:45,547 --> 00:00:47,420
これが Pharo の表現式になることが
おわかりでしょうか。

15
00:00:48,000 --> 00:00:52,490
つまり、このビデオでは

16
00:00:52,657 --> 00:00:55,170
ダイスを表現するクラスと

17
00:00:55,337 --> 00:00:57,420
ダイスのハンドルを表現するクラスを
実装します。

18
00:00:58,660 --> 00:00:59,770
では始めましょう。

19
00:01:00,870 --> 00:01:04,290
始めに、パッケージを定義します。

20
00:01:05,710 --> 00:01:06,790
Dice と呼ぶことにします。

21
00:01:06,957 --> 00:01:11,860
他のものは見たくないので

22
00:01:12,027 --> 00:01:16,660
このビデオでは

23
00:01:16,827 --> 00:01:19,450
コードをデバッガーで書くやり方は
しないつもりです。

24
00:01:19,617 --> 00:01:22,210
ほかのビデオでお見せした方法ですが

25
00:01:22,377 --> 00:01:24,410
ケースバイケースで、そうすべき機会があれば
そうすることもあるでしょう。

26
00:01:25,490 --> 00:01:30,030
ここで、Die クラスを定義します。

27
00:01:30,197 --> 00:01:31,370
面の数 faces を持っています。

28
00:01:32,100 --> 00:01:35,630
コンパイルします。
クラスコメントを追加します。

29
00:01:43,380 --> 00:01:45,890
当面は大したことはありません。
とてもとても単純なものですから。

30
00:01:47,550 --> 00:01:52,360
このオブジェクトの初期化を

31
00:01:52,527 --> 00:01:53,950
作る作業を始めてみましょう。

32
00:02:00,450 --> 00:02:02,260
こんな風にやります。

33
00:02:10,190 --> 00:02:13,560
スーパークラスの初期化を呼んで

34
00:02:13,727 --> 00:02:18,140
面の数のデフォルト値として6を代入します。

35
00:02:18,307 --> 00:02:19,140
それが最も一般的なダイスなので。

36
00:02:19,820 --> 00:02:22,530
ここでテストクラスを作り始めます。

37
00:02:22,697 --> 00:02:25,640
一旦作ったものを

38
00:02:25,807 --> 00:02:26,900
壊してしまわないようにするためです。

39
00:02:27,260 --> 00:02:30,450
テストクラスは
TestCaseクラスのサブクラスです。

40
00:02:30,617 --> 00:02:34,100
DieTest クラスとします。

41
00:02:34,370 --> 00:02:37,510
これでテストクラスができました。

42
00:02:37,790 --> 00:02:40,220
最初にやるべきテストの1つとして

43
00:02:40,387 --> 00:02:42,480
いつもそうする必要はありませんが

44
00:02:42,647 --> 00:02:46,650
ちゃんと動くテストから始めたいのです。

45
00:02:47,840 --> 00:02:52,120
今の所、あまり多くのものはないので
初期化はOKだと言いたいです。

46
00:02:53,820 --> 00:02:56,160
ここでお見せするのは

47
00:02:56,327 --> 00:02:59,770
例外が出てくることを確認するテストや

48
00:02:59,937 --> 00:03:01,440
例外が出ないことを確認するテストの
例にもなっています。

49
00:03:02,180 --> 00:03:04,590
では書いてみます。

50
00:03:04,757 --> 00:03:06,460
Die new は Error を投げてはいけない。

51
00:03:18,120 --> 00:03:19,170
どういう意味でしょう？

52
00:03:19,337 --> 00:03:23,290
「Die new というコードを実行した時に

53
00:03:23,457 --> 00:03:25,600
エラーが発生してはいけない」
という意味です。

54
00:03:28,170 --> 00:03:32,560
このテストを分類して実行します。

55
00:03:32,727 --> 00:03:35,550
グリーンです。ばっちりです。

56
00:03:36,000 --> 00:03:40,020
ではここで

57
00:03:40,187 --> 00:03:44,540
ダイスを振るメソッドを定義します。

58
00:03:44,707 --> 00:03:48,610
Pharo には 

59
00:03:48,777 --> 00:03:49,720
atRandom というメソッドがあります。

60
00:03:49,887 --> 00:03:53,940
atRandomは何をするのでしょうか？

61
00:03:54,480 --> 00:03:57,780
そのメソッドの機能は…そうですね

62
00:03:58,310 --> 00:04:00,770
実装を見て確認してみましょう。

63
00:04:00,937 --> 00:04:03,620
atRandomは何をするのでしょう？

64
00:04:04,870 --> 00:04:09,070
それは 1 から self までの
ランダムな整数を返します。ピッタリですね。

65
00:04:10,910 --> 00:04:13,910
なので、新しいメソッドを

66
00:04:15,290 --> 00:04:19,220
operationsに定義します。

67
00:04:21,160 --> 00:04:22,230
何をしましょうか？

68
00:04:22,397 --> 00:04:26,640
roll（転がす）です。

69
00:04:27,570 --> 00:04:28,203
「ランダムな出目を返す」ということです。

70
00:04:35,750 --> 00:04:37,400
そこでこのメソッドのテストを書きます。

71
00:04:40,490 --> 00:04:43,590
testRolling
何をするのでしょう？

72
00:04:44,120 --> 00:04:49,040
ダイスを作ります。

73
00:04:49,207 --> 00:04:49,840
d:= Die new

74
00:04:51,210 --> 00:04:53,140
そして
1000 timesRepeat:

75
00:04:54,420 --> 00:04:58,240
何を？
d roll

76
00:05:03,620 --> 00:05:07,580
そしてこれが
1 から 6 の間であってほしいのです。


77
00:05:07,747 --> 00:05:12,640
between: and:
いいですね。

78
00:05:12,807 --> 00:05:15,560
between: 1 and: 6

79
00:05:15,820 --> 00:05:18,510
これはあまり良くないです。
というのも、ここでは

80
00:05:18,677 --> 00:05:22,470
6面ダイスのテストしか書いていません。

81
00:05:22,637 --> 00:05:25,310
ダイスの面の数に従って動くべきです。

82
00:05:25,640 --> 00:05:26,580
それは後回しにしましょう。

83
00:05:26,830 --> 00:05:27,463
なのでコンパイルします。

84
00:05:32,840 --> 00:05:35,620
エラーになりました。こうです。

85
00:05:37,910 --> 00:05:39,170
これでテストができました。

86
00:05:39,337 --> 00:05:41,460
ここで保存しましょう。
Dice パッケージがあるので

87
00:05:41,627 --> 00:05:44,590
ローカルに保存します。
Save です。

88
00:05:44,757 --> 00:05:49,000
練習で他のものをいくつか作ったので

89
00:05:49,167 --> 00:05:51,710
新しいものを作ります。
「新しいバージョン

90
00:05:56,530 --> 00:06:00,780
ダイスを振るのとテスト」
これで良し、と。

91
00:06:01,030 --> 00:06:02,370
はい、これで保存されました。

92
00:06:11,480 --> 00:06:14,610
ここで、インスタンス生成の
インターフェイスを変えようと思います。

93
00:06:14,777 --> 00:06:18,890
まずはカテゴリーを整理します。

94
00:06:19,810 --> 00:06:22,200
インスタンス生成を少し変えたい。

95
00:06:22,367 --> 00:06:26,390
ダイスを作るときに

96
00:06:26,557 --> 00:06:28,090
面の数をつかいたい。

97
00:06:39,290 --> 00:06:42,610
もう解ったはずですが
この式の中で

98
00:06:42,777 --> 00:06:46,030
faces は Die クラスへ
送られたメッセージであって

99
00:06:46,197 --> 00:06:48,610
Die クラスのインスタンスへの
メッセージでははありません。

100
00:06:49,090 --> 00:06:51,880
インスタンスへのメッセージは今のところ
roll メソッドかまたは別のクラスのメソッドだけです。

101
00:06:52,047 --> 00:06:55,040
これで理解してほしいのは

102
00:06:55,207 --> 00:06:58,900
いつクラスレベルへ行くべきか、あるいは
行くべきでないか、ということです。

103
00:06:59,350 --> 00:07:00,710
まずはテストを書きましょう。

104
00:07:03,050 --> 00:07:06,420
betterInterface

105
00:07:08,790 --> 00:07:10,200
同じロジックで続けると

106
00:07:12,230 --> 00:07:18,080
testBetterCreationInterface

107
00:07:18,247 --> 00:07:20,950
ここで例えばこんなことをしたいのです。

108
00:07:22,680 --> 00:07:23,640
そしてこれは faces です。

109
00:07:30,620 --> 00:07:32,420
ゆっくりやります。

110
00:07:32,950 --> 00:07:36,840
ここに行ってinstance creation と入力して
faces: anInteger

111
00:07:46,560 --> 00:07:49,000
短く書くこともできますが
ここでは

112
00:07:49,167 --> 00:07:50,530
「穏やかな」やり方をします。

113
00:07:51,000 --> 00:07:52,940
ダイスを作ります。

114
00:07:53,890 --> 00:07:57,740
self new と書きます。
ここでの self は Die クラス自身です。

115
00:07:58,220 --> 00:08:00,410
インスタンスを作る
と伝えます。

116
00:08:00,577 --> 00:08:03,620
そして
このインスタンスに対して

117
00:08:03,787 --> 00:08:08,410
アクセサーを使って
引数として渡された値を代入します。

118
00:08:08,577 --> 00:08:12,130
当然、今まさに作ったダイスを返します。

119
00:08:13,860 --> 00:08:16,920
このコードが実行して
ちゃんと動きません。

120
00:08:17,087 --> 00:08:19,950
faces はまだ存在していないからです。
なので心配しなくていいです。

121
00:08:20,117 --> 00:08:22,760
テストが OK ではないですが

122
00:08:22,927 --> 00:08:27,720
正常なことです。これを実行すれば
execute this

123
00:08:27,887 --> 00:08:29,520
例えば、デバッグして見てみれば

124
00:08:33,640 --> 00:08:38,360
Over をクリックすると

125
00:08:38,527 --> 00:08:41,430
faces というメッセージがわからない
と言ってきます。

126
00:08:41,910 --> 00:08:45,770
ここでは「穏やかな」やり方でいくので
デバッガではやりません。

127
00:08:46,830 --> 00:08:49,600
その通りで
アクセサーを追加する必要があります。

128
00:08:52,910 --> 00:08:57,390
faces: anInteger
と書いて

129
00:08:57,557 --> 00:09:01,520
faces := anInteger
と書きます。

130
00:09:05,020 --> 00:09:08,110
ついでに読み出しのアクセサーを書きます。

131
00:09:09,330 --> 00:09:11,500
これを返します。

132
00:09:13,250 --> 00:09:14,450
これでテストはグリーンです。

133
00:09:15,240 --> 00:09:19,180
なので保存します。
save

134
00:09:19,347 --> 00:09:22,250
ダイスのより良い生成メソッドと
テスト

135
00:09:22,417 --> 00:09:23,050
よしと。

136
00:09:31,610 --> 00:09:33,670
これで

137
00:09:33,837 --> 00:09:37,650
ダイスハンドルの定義を
始めることができます。

138
00:09:38,690 --> 00:09:42,050
ダイスハンドルについて

139
00:09:42,217 --> 00:09:44,000
どんな風に書きたいでしょうか？

140
00:09:44,167 --> 00:09:45,450
DiceHandle new addDie:
みたいに書きたいと思います。

141
00:09:49,300 --> 00:09:53,290
そして新しいダイスを作るわけです。
die faces: 6; addDie:

142
00:09:55,210 --> 00:09:59,680
Die faces: 10

143
00:10:07,260 --> 00:10:12,040
今回は

144
00:10:12,207 --> 00:10:13,580
テストクラスから書き始めたいと思います。

145
00:10:15,250 --> 00:10:19,930
なので TestCase から継承した新しいクラスです。

146
00:10:20,290 --> 00:10:22,330
よし。
新しいテストクラスができました。

147
00:10:24,000 --> 00:10:26,730
そしてテストを定義します。

148
00:10:30,220 --> 00:10:32,850
ハンドルを作って

149
00:10:33,017 --> 00:10:35,140
正しいダイスが入っているか
チェックします。

150
00:10:35,307 --> 00:10:39,380
testAdding
コードを再利用します。

151
00:10:39,547 --> 00:10:43,730
そうしない理由はないですよね。

152
00:10:45,530 --> 00:10:48,060
なのでここで

153
00:10:54,310 --> 00:10:58,940
handle　さらに yourself

154
00:10:59,107 --> 00:11:01,960
メッセージレシーバーが欲しいので。
つまりハンドルであって

155
00:11:02,127 --> 00:11:03,690
渡した引数ではなく。

156
00:11:04,500 --> 00:11:08,260
さあ、何をしたらいいでしょう？

157
00:11:08,427 --> 00:11:12,520
self assert: [h diceNumber

158
00:11:13,960 --> 00:11:14,593
equals 2

159
00:11:20,700 --> 00:11:23,380
コンパイルします。
明らかなことですが、システムが

160
00:11:23,547 --> 00:11:25,930
変数 DiceHandle を知らないと言っています。

161
00:11:26,097 --> 00:11:26,730
そういうクラスが欲しいのですか？と。

162
00:11:26,897 --> 00:11:27,960
はい、クラスです。

163
00:11:28,560 --> 00:11:29,750
これで定義されます。

164
00:11:29,917 --> 00:11:31,340
いずれダイスを持たないといけないことは
もう分かっていることなので

165
00:11:31,507 --> 00:11:36,440
ちょうどいい機会なので

166
00:11:36,870 --> 00:11:39,580
ここでインスタンス変数を入れます。

167
00:11:39,747 --> 00:11:40,860
これをコンパイルします。

168
00:11:41,790 --> 00:11:45,720
これで（テストは）レッドです。
addDie: が定義されていないからです。

169
00:11:47,620 --> 00:11:48,570
なので定義しましょう。

170
00:11:48,737 --> 00:11:51,620
その前に
ハンドルを初期化しておいたほうがいいですね。

171
00:11:54,240 --> 00:11:56,660
こんな風にします。

172
00:11:56,827 --> 00:11:57,890
後々のバグを予防できます。

173
00:12:02,890 --> 00:12:04,560
dice : = OrderedCollection new.

174
00:12:04,727 --> 00:12:05,360
Recategorize（分類し直し）

175
00:12:21,880 --> 00:12:24,760
そして、これでテストできるはずです。

176
00:12:24,927 --> 00:12:27,730
で、クラッシュします。
はいはい、大丈夫です。

177
00:12:27,897 --> 00:12:30,200
addDie: を作ります。

178
00:12:30,530 --> 00:12:31,163
adding です。

179
00:12:35,330 --> 00:12:38,030
このメソッドを実装しなければならない
と言ってきます。

180
00:12:38,197 --> 00:12:39,080
まあその通りです。

181
00:12:39,247 --> 00:12:42,430
dice add: aDie
と書きます。

182
00:12:43,590 --> 00:12:45,920
はい、ばっちりです。
テストはまだ動きません。

183
00:12:46,087 --> 00:12:48,150
diceNumberをまだ定義していないからです。

184
00:12:48,317 --> 00:12:52,120
では定義しましょう。
はい、diceNumber です。

185
00:12:52,287 --> 00:12:56,780
今回は accessing に定義します。

186
00:12:57,350 --> 00:12:58,800
そして diceNumber ですが
何をしましょうか？

187
00:12:58,967 --> 00:13:00,330
返さないといけないのは

188
00:13:06,290 --> 00:13:08,110
ダイスの個数です。またコンパイルします。
テストを進めるとグリーンになるはずです。

189
00:13:09,940 --> 00:13:12,510
テストはグリーンになったので

190
00:13:12,677 --> 00:13:14,860
保存します。

191
00:13:17,250 --> 00:13:18,580
addDie とテスト。

192
00:13:24,560 --> 00:13:28,090
テストを改良することもできます。

193
00:13:28,257 --> 00:13:31,900
ここでは 2つのダイスをくわえていますが

194
00:13:32,067 --> 00:13:35,180
同じダイスを2回追加しても

195
00:13:35,347 --> 00:13:37,610
大丈夫かチェックします。

196
00:13:38,280 --> 00:13:39,340
testAddingTwiceTheSameDieIsOK と。

197
00:13:49,040 --> 00:13:50,290
ここで何をしましょう？

198
00:13:50,457 --> 00:13:54,530
6面ダイスと6面ダイスを足したら
ダイスは2つになるはずです。

199
00:13:57,030 --> 00:13:59,940
これでテストを実行します。
グリーンです。素晴らしい。

200
00:14:01,230 --> 00:14:04,700
さて、ここで

201
00:14:05,880 --> 00:14:08,960
2 つのダイスを追加することを定義できたら

202
00:14:11,240 --> 00:14:14,900
よいのですが、その前に
やっておくことがあります。

203
00:14:15,067 --> 00:14:17,210
見てください。気に入らないのは

204
00:14:17,377 --> 00:14:19,030
例えばこれをインスペクトすると

205
00:14:23,950 --> 00:14:28,740
ダイスの中身がわかりません。

206
00:14:28,907 --> 00:14:31,530
それでデバッグするのは実践的ではないですね。

207
00:14:31,697 --> 00:14:33,030
デバッガーではこれが見えないのです。

208
00:14:33,370 --> 00:14:36,090
なので、先に進める前に
これを改良しておきたいのです。

209
00:14:36,257 --> 00:14:38,370
printing プロトコルに
メソッドを追加します。

210
00:14:38,660 --> 00:14:41,710
printOn: メソッドです。

211
00:14:44,220 --> 00:14:46,840
システムの全てのオブジェクトに
定義されているメソッドで

212
00:14:47,007 --> 00:14:50,380
オブジェクトを

213
00:14:50,547 --> 00:14:53,490
テキスト表現に変換して

214
00:14:55,380 --> 00:14:58,780
ストリームに渡します。

215
00:14:58,947 --> 00:15:00,420
今回は表現をより詳細にします。

216
00:15:01,890 --> 00:15:03,500
こうすると何もしないのと同じです。

217
00:15:03,667 --> 00:15:07,630
super printOn: をすると
前と何も変わりません。

218
00:15:07,797 --> 00:15:09,230
そしてさらに

219
00:15:09,397 --> 00:15:13,220
aStream nextPutAll:
で文字をストリームに入れていきます。
put characters in the 

220
00:15:13,387 --> 00:15:15,220
まず何を入れましょう？

221
00:15:16,090 --> 00:15:18,330
空白と括弧を書きます。

222
00:15:18,497 --> 00:15:19,880
このほうが良い感じでしょう。

223
00:15:20,450 --> 00:15:23,550
そして faces をどうするかですが

224
00:15:23,717 --> 00:15:27,780
数値を文字列に変換して
全部を連結して

225
00:15:28,360 --> 00:15:30,760
括弧を閉じます。

226
00:15:31,150 --> 00:15:34,930
こうして、インスペクターを閉じて
もう一度開きます。

227
00:15:35,850 --> 00:15:38,630
6面ダイスと

228
00:15:38,797 --> 00:15:40,480
10面ダイスがあります。
much 

229
00:15:40,647 --> 00:15:44,140
見ての通り、前よりも良いです。
バグが出てきた時に、きっと手助けになるでしょう。

230
00:15:44,850 --> 00:15:48,140
大したことは何もしていないので
テストは動いています。

231
00:15:49,450 --> 00:15:53,340
また保存します。大した手間ではありません。
表示、と。

232
00:15:55,220 --> 00:15:56,400
Die の printOn: と。

233
00:16:03,030 --> 00:16:08,000
これでよし。ではテストを作りましょう。

234
00:16:08,167 --> 00:16:09,580
いや、テストを作るのではなく
直接やりましょう。

235
00:16:10,080 --> 00:16:12,490
operations プロトコルで

236
00:16:13,600 --> 00:16:17,890
さて

237
00:16:18,057 --> 00:16:22,530
これを定義する方法はいくつかあります。

238
00:16:22,820 --> 00:16:25,040
そのうち1つをお見せします。
一番良い方法というわけではありませんが

239
00:16:25,207 --> 00:16:27,160
おそらく一番解りやすい方法です。

240
00:16:27,530 --> 00:16:29,130
コンパクトに

241
00:16:29,297 --> 00:16:31,490
1行で書くこともできますが

242
00:16:31,657 --> 00:16:33,150
inject:into:のようなイテレーターを使います。
今回はループを使います。

243
00:16:33,550 --> 00:16:34,210
では何をしましょうか？

244
00:16:34,377 --> 00:16:36,860
0 で初期化された変数を使って

245
00:16:37,390 --> 00:16:42,320
全てのダイスについてループして

246
00:16:42,487 --> 00:16:47,120
ループのそれぞれの周回で
ダイスを取り出して

247
00:16:47,287 --> 00:16:47,920
このダイスで何をしましょう？

248
00:16:48,120 --> 00:16:51,900
ダイスを振って
結果を変数に

249
00:16:52,067 --> 00:16:53,440
足していきます。

250
00:16:55,640 --> 00:17:00,310
何も大したことのないですが
とても、とても明示的です。

251
00:17:02,000 --> 00:17:05,380
ここでインスペクトして

252
00:17:05,547 --> 00:17:10,510
roll します。5 です。
これだけでは動いている証明にはなりません。

253
00:17:11,210 --> 00:17:12,140
もう一度やってみます。

254
00:17:12,307 --> 00:17:13,140
11 です。いいでしょう、動いています。

255
00:17:13,950 --> 00:17:16,120
テストを書いてみます。

256
00:17:16,287 --> 00:17:19,920
そうしない理由はないので
テストします。

257
00:17:21,590 --> 00:17:22,940
これを使って
ここは Rolling としましょう。

258
00:17:26,960 --> 00:17:30,940
では、これをどうテストしましょうか？

259
00:17:31,107 --> 00:17:35,760
1からダイスの最大値の間のはずです。
It has to be between one and
the maximum of the number of dice.

260
00:17:38,000 --> 00:17:42,100
なので、こうしましょう。
So we will do this.

261
00:17:42,267 --> 00:17:42,900
これをする
We

262
00:17:48,280 --> 00:17:49,930
メソッドを定義できますね。
could define a method
doing this.

263
00:17:50,240 --> 00:17:53,040
最大値を求めるメソッドを作りましょう。
Let's create a method
defining the maximum.

264
00:17:56,720 --> 00:18:00,100
operations の maxValue です。
"Operation maxValue".

265
00:18:02,480 --> 00:18:03,240
最大値とは何でしょう？

266
00:18:03,407 --> 00:18:05,020
これに似ているはずです。
It is very close to this.

267
00:18:05,780 --> 00:18:10,000
ここではダイスを「振る」かわりに

268
00:18:11,440 --> 00:18:12,430
面の数を訊きます。
I will ask for the faces.

269
00:18:16,560 --> 00:18:20,490
ではチェックしてみましょう。
インスペクトして
Let's check. If I do
"Inspect", there

270
00:18:21,830 --> 00:18:24,820
maxValue します。16 です。
I do "maxValue", "16".

271
00:18:28,490 --> 00:18:30,480
はい、10 と 6 なので正しいです。
Yes, it's right 10 and 6.

272
00:18:30,647 --> 00:18:33,090
では maxVallue のテストを書きましょう。

273
00:18:37,010 --> 00:18:41,600
これを使って
maxValue は

274
00:18:41,767 --> 00:18:42,400
16 になるはずです。

275
00:18:45,320 --> 00:18:48,150
見ての通り
テストではとても汚いコードを書きましたが

276
00:18:48,317 --> 00:18:51,320
最終的には

277
00:18:51,487 --> 00:18:53,690
メソッドを書いて使った方が良いです。

278
00:18:54,080 --> 00:18:58,370
ではここで roll メソッドのテストに戻ります。

279
00:18:58,820 --> 00:19:02,340
roll をします。

280
00:19:05,900 --> 00:19:08,770
そしてその結果は

281
00:19:08,937 --> 00:19:11,000
1 から h maxValue の間

282
00:19:14,230 --> 00:19:15,690
でなければなりません。

283
00:19:24,080 --> 00:19:26,000
実行すると、はい、動きます。

284
00:19:28,120 --> 00:19:30,870
あまり統計的な根拠はないですが
This is not very statistical,
so here we could do

285
00:19:31,037 --> 00:19:35,800
something like
1000 timesRepeat: のようなこともできます。

286
00:19:36,000 --> 00:19:38,560
オッケーです。これで

287
00:19:42,220 --> 00:19:46,680
1000回テストができました。

288
00:19:47,740 --> 00:19:49,330
では保存します。素晴らしい。

289
00:19:49,497 --> 00:19:52,440
maxValue と

290
00:19:54,610 --> 00:19:56,030
rollとテストを追加。

291
00:20:03,940 --> 00:20:08,380
これでほとんど完成です。

292
00:20:08,547 --> 00:20:11,070
表現として

293
00:20:11,237 --> 00:20:13,680
Die faces: 6 ではなく

294
00:20:16,290 --> 00:20:17,670
1 D6
のように表現したいと思います。

295
00:20:17,837 --> 00:20:18,470
そして

296
00:20:25,510 --> 00:20:27,630
これは詰まるところ

297
00:20:27,797 --> 00:20:31,050
整数オブジェクトにメッセージ D6 を送る
ということです。

298
00:20:31,770 --> 00:20:34,540
なので、Integerクラスを見てみましょう。

299
00:20:34,707 --> 00:20:39,620
これからやろうとしていることは

300
00:20:39,787 --> 00:20:43,660
クラスへの拡張を定義することです。

301
00:20:43,827 --> 00:20:45,010
クラスへの拡張とは？

302
00:20:45,890 --> 00:20:50,350
メソッドをパッケージと同じ名前で
パッケージングするのですが

303
00:20:50,800 --> 00:20:53,360
これからお見せします。

304
00:20:53,527 --> 00:20:57,420
プロトコルを追加します。
先頭に * を付けます。

305
00:20:57,587 --> 00:21:00,780
*Dice とすることで
灰色の表示になります。

306
00:21:00,947 --> 00:21:02,900
これはこのメソッドは
このパッケージといっしょに

307
00:21:03,067 --> 00:21:04,460
パッケージされるということです。
やってみましょう。

308
00:21:04,900 --> 00:21:08,950
想像してみましょう。
D6とは何でしょう？

309
00:21:10,000 --> 00:21:13,570
D6... ちょっと考えなければなりません。

310
00:21:21,050 --> 00:21:24,250
まずはハンドルを作ります。

311
00:21:24,417 --> 00:21:25,510
2 D6 とかの場合もありますから。

312
00:21:27,210 --> 00:21:31,930
なので、handle と。

313
00:21:32,097 --> 00:21:32,730
DiceHandle new

314
00:21:37,120 --> 00:21:38,280
はい、これでできました。

315
00:21:39,380 --> 00:21:42,110
これで、レシーバー回数ということで
I will do

316
00:21:42,277 --> 00:21:45,430
self つまり自分の整数で
timesRepeat:

317
00:21:46,370 --> 00:21:50,140
timesRepeat: を本当に多く使いましたが
こんなことは珍しいです。

318
00:21:51,900 --> 00:21:54,120
timesRepeat: [handle addDie:
で、何でしょう。

319
00:21:56,790 --> 00:22:01,150
Die faces:
そして

320
00:22:02,000 --> 00:22:03,720
6 ですよね。

321
00:22:05,890 --> 00:22:09,830
これでハンドルを返せば良さそうですね。

322
00:22:11,220 --> 00:22:12,330
さあ動くでしょうか？

323
00:22:12,497 --> 00:22:14,950
こんな風にテストをして
テストを書きます。

324
00:22:15,470 --> 00:22:20,380
しかし 2 D6
インスペクトすると、ほら

325
00:22:20,547 --> 00:22:22,390
2つの D6 が得られます。すごい。

326
00:22:23,190 --> 00:22:24,290
テストを書きましょう。

327
00:22:25,640 --> 00:22:27,140
これらのテストを分類しておきます。

328
00:22:28,150 --> 00:22:29,330
testNewSyntax
と書きます。

329
00:22:33,950 --> 00:22:36,420
ここで今は D6 しかありません。
後で一般化します。

330
00:22:38,010 --> 00:22:40,000
これと全く同じことをしたいわけです。

331
00:22:40,167 --> 00:22:44,440
そしてハンドルが得られるはず。
では、2 D6 として

332
00:22:47,020 --> 00:22:49,620
self assert: と。

333
00:22:53,310 --> 00:22:54,430
何をテストしましょう？

334
00:22:54,597 --> 00:22:56,470
diceNumber は 2 のはずです。

335
00:23:02,880 --> 00:23:05,420
お気付きかもしれませんが

336
00:23:05,587 --> 00:23:09,160
ここは = 2 とすることもできます。

337
00:23:09,810 --> 00:23:12,080
一般には、assert:equals: を使う方が良いです。

338
00:23:12,540 --> 00:23:14,310
というのも、このように
エラーになった時に

339
00:23:14,477 --> 00:23:18,020
「これを期待していたのに、これが得られた」
とシステムが言ってくれます。

340
00:23:18,630 --> 00:23:22,910
= を使うと、システムは
「間違ってます」としか言えません。

341
00:23:23,680 --> 00:23:26,480
この場合には

342
00:23:26,647 --> 00:23:28,850
開発者としてはassert:equals:を使った方が
良いです。

343
00:23:30,580 --> 00:23:33,340
「2 を期待していましたが、3 が得られました」

344
00:23:33,560 --> 00:23:34,680
のようになるので。

345
00:23:35,860 --> 00:23:37,060
ここは、こうします。

346
00:23:37,510 --> 00:23:38,780
はい、動きました。

347
00:23:39,320 --> 00:23:41,940
もっと賢い方法で

348
00:23:42,107 --> 00:23:43,090
このテストができるでしょうか？

349
00:23:43,257 --> 00:23:44,240
今のところ、これで十分です。

350
00:23:44,860 --> 00:23:46,640
今、このパッケージには

351
00:23:46,807 --> 00:23:50,200
D6 という拡張があることがわかります。

352
00:23:50,690 --> 00:23:55,480
これを後で一般化して
with 

353
00:23:56,120 --> 00:23:57,550
D: aNumberOfFaces とします。

354
00:24:01,360 --> 00:24:03,870
ここが aNumberOfFaces になります。

355
00:24:05,200 --> 00:24:08,000
そして D6 を書き直します。

356
00:24:08,137 --> 00:24:12,580
D6 をこんな風に書きます。
このほうが良いです。

357
00:24:12,747 --> 00:24:16,660
self D: 6 を返します。

358
00:24:19,050 --> 00:24:20,750
他もやってしまいます。

359
00:24:20,917 --> 00:24:24,370
D4

360
00:24:26,020 --> 00:24:30,870
D2。
ダイスというよりコインですね。

361
00:24:31,220 --> 00:24:35,640
D10 と D20.

362
00:24:36,440 --> 00:24:37,570
これが原則です。

363
00:24:41,540 --> 00:24:45,930
ではテストを走らせましょう。
実装を変更したのですから。

364
00:24:47,010 --> 00:24:49,370
2 D6... 動いています。

365
00:24:49,830 --> 00:24:50,690
では保存しましょう。

366
00:24:59,670 --> 00:25:03,320
やり残したことはあるでしょうか？

367
00:25:03,680 --> 00:25:08,030
あります。
ハンドル同士を足し合わせることです。

368
00:25:09,300 --> 00:25:11,600
何をテストしましょうか？

369
00:25:11,767 --> 00:25:14,640
今回確認したいのは
ハンドルを足すことなので

370
00:25:18,710 --> 00:25:23,240
testAddingHandles

371
00:25:23,407 --> 00:25:25,590
(ここで新しい表現を使うことができるのは

372
00:25:25,757 --> 00:25:26,440
良いですね)

373
00:25:26,960 --> 00:25:28,940
テストしたいことは

374
00:25:29,107 --> 00:25:33,820
2 D20 + 3 D5

375
00:25:34,000 --> 00:25:38,570
いや、3 D6 にしましょう。
（問題を複雑にしないようにしましょう）

376
00:25:38,737 --> 00:25:42,050
いくつあるでしょうか？

377
00:25:43,160 --> 00:25:46,770
diceNumber は 5 のはずです。

378
00:25:48,180 --> 00:25:52,270
ここで、+ 演算子を定義しなければなりませんね。

379
00:25:52,870 --> 00:25:55,520
Pharo では、+ は演算子ではありません。
単なるメッセージです。

380
00:25:55,687 --> 00:25:59,230
なので DiceHandle クラスにメッセージを定義します。

381
00:26:00,530 --> 00:26:02,850
+ と書きます。

382
00:26:04,650 --> 00:26:05,520
で、 aDiceHandle です。

383
00:26:07,530 --> 00:26:09,410
ここで考えてみましょう。

384
00:26:09,577 --> 00:26:11,770
レシーバー（ハンドル）を書き変える方法と

385
00:26:11,937 --> 00:26:12,840
関数的な方法があります。

386
00:26:13,130 --> 00:26:14,740
関数的な方法のほうが好みです。

387
00:26:14,907 --> 00:26:17,470
関数的な方法では新しいハンドルを作ります。

388
00:26:20,180 --> 00:26:23,690
そこで新しいハンドルを作ります。

389
00:26:26,060 --> 00:26:27,650
handle := self class new

390
00:26:29,540 --> 00:26:34,060
ここでは DiceHandle と書くのを避けました。

391
00:26:34,227 --> 00:26:36,360
後でその理由を説明するレッスンがあります。

392
00:26:36,527 --> 00:26:37,770
それほど先ではありません。

393
00:26:37,937 --> 00:26:39,800
一般的に、クラス名をハードコードすべきではない
ということです。

394
00:26:40,430 --> 00:26:42,530
第7週かその辺りで

395
00:26:42,697 --> 00:26:44,040
きちんと説明します。

396
00:26:44,740 --> 00:26:49,660
self dice do:
とすると

397
00:26:49,827 --> 00:26:53,480
自分が持つダイスを列挙します。
そしてそれをハンドルに加えていきます。

398
00:26:53,647 --> 00:26:55,610
handle addDie: each

399
00:26:59,780 --> 00:27:03,660
そして同じことをします。

400
00:27:03,827 --> 00:27:05,720
こちらでは self ではなく…

401
00:27:05,887 --> 00:27:07,420
ああ、このメッセージはわかりませんね。
システムがそう言っています。

402
00:27:07,587 --> 00:27:09,370
それで気付いたのですが
まだ定義していません。

403
00:27:09,820 --> 00:27:12,790
なので diceHandle にも動かないわけですが

404
00:27:15,630 --> 00:27:20,480
とりあえず、まずはコンパイルしてしまって
後で直しましょう。

405
00:27:21,230 --> 00:27:22,450
どういうことかというと

406
00:27:22,617 --> 00:27:24,790
アクセサーが足りません。diceです。

407
00:27:25,280 --> 00:27:28,770
なのでここで dice を書きましょう。

408
00:27:28,937 --> 00:27:32,060
dice は
自分のダイスのコレクションを返します。

409
00:27:32,227 --> 00:27:35,280
これでテストしてみます。

410
00:27:35,700 --> 00:27:38,690
テストは大丈夫です。素晴らしい。
完成が近いということです。

411
00:27:38,857 --> 00:27:43,610
保存します。
ハンドル同士の足し算

412
00:27:44,810 --> 00:27:46,690
はい、オッケーです。

413
00:27:49,820 --> 00:27:53,770
つまりこれで

414
00:27:57,300 --> 00:28:02,210
2 D4 と書いて

415
00:28:02,377 --> 00:28:06,380
roll つまり振ることができます。
そして数が返ってきます。

416
00:28:08,000 --> 00:28:10,400
さあ、これでダンジョンズ＆ドラゴンズを
プレーすることができます。

417
00:28:11,200 --> 00:28:15,870
ここまでやったことは

418
00:28:17,570 --> 00:28:19,480
メソッドを書いて
テストを書いて

419
00:28:19,647 --> 00:28:23,010
テストを走らせて
システムクラスを拡張しました。

420
00:28:23,177 --> 00:28:27,000
Integerクラスにこのパッケージにリンクした
拡張をつけることで

421
00:28:27,167 --> 00:28:30,590
このパッケージがロードされた時のみ
見えます。

422
00:28:32,290 --> 00:28:34,580
そして演算子のオーバーロードもしました。

423
00:28:34,747 --> 00:28:39,320
実際には単に + メッセージの
新しい定義をしただけです。

424
00:28:39,487 --> 00:28:43,600
Pharo では足し算は単なるメッセージなので。

425
00:28:43,767 --> 00:28:48,160
これによって良い感じのDSLで
記述できるようになりました。

426
00:28:49,900 --> 00:28:50,850
さあ、あなたがコードを書く番です！


