WEBVTT 00:00:01.910 --> 00:00:04.410 This video is a Redo for the MOOC. 00:00:04.577 --> 00:00:07.030 Redo means do it yourself, 00:00:07.520 --> 00:00:09.540 watch the video and do what is shown step by step. 00:00:10.060 --> 00:00:13.470 It is also an invitation to look at how we program. 00:00:13.720 --> 00:00:17.680 I won't follow a precise script, 00:00:17.847 --> 00:00:20.060 I will try to do it, but if I encounter bugs or 00:00:20.227 --> 00:00:23.090 things like that, I'm gonna handle them as I go along. 00:00:24.870 --> 00:00:29.130 In this video, the idea is to program a little 00:00:29.297 --> 00:00:32.040 language that you can find in role-playing games like 00:00:32.207 --> 00:00:35.930 "Dungeons and Dragons". For example, 00:00:36.097 --> 00:00:38.800 for the ones who have this expression, what 00:00:38.967 --> 00:00:40.010 does this expression mean? 00:00:40.420 --> 00:00:45.380 It means: you must throw 2 20-sided dice and 1 4-sided. 00:00:45.547 --> 00:00:47.420 You'll see it can be a Pharo expression. 00:00:48.000 --> 00:00:52.490 So in this video we're going 00:00:52.657 --> 00:00:55.170 to implement a class representing a die and a class 00:00:55.337 --> 00:00:57.420 representing a handful of dice. 00:00:58.660 --> 00:00:59.770 So let's begin. 00:01:00.870 --> 00:01:04.290 We begin with defining a package. 00:01:05.710 --> 00:01:06.790 We call this package "Dice". 00:01:06.957 --> 00:01:11.860 I don't really want to see 00:01:12.027 --> 00:01:16.660 other things. So in this 00:01:16.827 --> 00:01:19.450 video I won't code in the 00:01:19.617 --> 00:01:22.210 debugger, you've seen it in another video, I will 00:01:22.377 --> 00:01:24.410 do it on a case-by-case basis, in an opportunistic way. 00:01:25.490 --> 00:01:30.030 Here I define the "Die" class which 00:01:30.197 --> 00:01:31.370 has a certain number of "faces". 00:01:32.100 --> 00:01:35.630 I compile. I add a class comment. 00:01:43.380 --> 00:01:45.890 For the moment, not much thing because it is very very simple. 00:01:47.550 --> 00:01:52.360 We are starting to enable our 00:01:52.527 --> 00:01:53.950 object to be initialized. 00:02:00.450 --> 00:02:02.260 I will do it like this. 00:02:10.190 --> 00:02:13.560 I call for an initialization of the super-class, 00:02:13.727 --> 00:02:18.140 by default I assign 6 faces to my die because it is 00:02:18.307 --> 00:02:19.140 the most common die. 00:02:19.820 --> 00:02:22.530 Now I'm starting to develop a 00:02:22.697 --> 00:02:25.640 tests class, to be sure that what we do 00:02:25.807 --> 00:02:26.900 doesn't break what has already been done. 00:02:27.260 --> 00:02:30.450 Tests classes are sub-classes of the TestCase class. 00:02:30.617 --> 00:02:34.100 We call it "DieTest". 00:02:34.370 --> 00:02:37.510 I have my tests class. 00:02:37.790 --> 00:02:40.220 One of the first tests to do, you 00:02:40.387 --> 00:02:42.480 don't have always to do it like this, but 00:02:42.647 --> 00:02:46.650 in any case I want to begin with a test that works well. 00:02:47.840 --> 00:02:52.120 As for the moment we don't have many things, I say that initialization is ok. 00:02:53.820 --> 00:02:56.160 This is also a way to show you 00:02:56.327 --> 00:02:59.770 how you can test that you can catch exceptions 00:02:59.937 --> 00:03:01.440 or that exceptions mustn't occur. 00:03:02.180 --> 00:03:04.590 Here I am saying: 00:03:04.757 --> 00:03:06.460 "Die new should not raise error". 00:03:18.120 --> 00:03:19.170 What does it mean? 00:03:19.337 --> 00:03:23.290 It means that when I execute this bit of code "Die 00:03:23.457 --> 00:03:25.600 new", no error must occur. 00:03:28.170 --> 00:03:32.560 I'm gonna classify my test and execute it. 00:03:32.727 --> 00:03:35.550 It's green. All right. 00:03:36.000 --> 00:03:40.020 So now, I'd like to define the 00:03:40.187 --> 00:03:44.540 method that makes a die roll. 00:03:44.707 --> 00:03:48.610 I know that in Pharo there must be a method 00:03:48.777 --> 00:03:49.720 called "at Random". 00:03:49.887 --> 00:03:53.940 At Random, what does it do? 00:03:54.480 --> 00:03:57.780 It enables to have... Ok... 00:03:58.310 --> 00:04:00.770 So now I look at the implementation to be sure 00:04:00.937 --> 00:04:03.620 it's ok. AtRandom, what does it do? 00:04:04.870 --> 00:04:09.070 It returns an integer at random from 1 to self, so it's perfect. 00:04:10.910 --> 00:04:13.910 So I'm gonna define a new 00:04:15.290 --> 00:04:19.220 method in Operations. 00:04:21.160 --> 00:04:22.230 What will it do? 00:04:22.397 --> 00:04:26.640 Roll. I say: "you return faces 00:04:27.570 --> 00:04:28.203 atRandom". 00:04:35.750 --> 00:04:37.400 So I write a test for this. 00:04:40.490 --> 00:04:43.590 TestRolling. What do we do now? 00:04:44.120 --> 00:04:49.040 We create a die. d:= die 00:04:49.207 --> 00:04:49.840 new 00:04:51.210 --> 00:04:53.140 And now I write "1000 timesRepeat". 00:04:54.420 --> 00:04:58.240 What? "d roll". 00:05:03.620 --> 00:05:07.580 And I want this to be between 1 and 6. 00:05:07.747 --> 00:05:12.640 "Between: and:", it's 00:05:12.807 --> 00:05:15.560 ok. "Between 1 and 6". 00:05:15.820 --> 00:05:18.510 It is not very good because here we created 00:05:18.677 --> 00:05:22.470 a test only for 6-sided dice, we could have said 00:05:22.637 --> 00:05:25.310 it works depending on the number of sides of the die. 00:05:25.640 --> 00:05:26.580 We will do it later. 00:05:26.830 --> 00:05:27.463 So I compile. 00:05:32.840 --> 00:05:35.620 I get an error. Here it is... 00:05:37.910 --> 00:05:39.170 It is ok, I have my test. 00:05:39.337 --> 00:05:41.460 Now it's time to save. Here I have my "Dice" 00:05:41.627 --> 00:05:44.590 package, I save it locally, "Save". 00:05:44.757 --> 00:05:49.000 I had created others before to train a little so I 00:05:49.167 --> 00:05:51.710 create a new one "New version with 00:05:56.530 --> 00:06:00.780 rolling and test". All right. 00:06:01.030 --> 00:06:02.370 Ok, it is saved. 00:06:11.480 --> 00:06:14.610 Now I'd like to change 00:06:14.777 --> 00:06:18.890 the creation interface. First we rearrange 00:06:19.810 --> 00:06:22.200 categories. If we want to change a little the creation 00:06:22.367 --> 00:06:26.390 interface. We say: "to create a die 00:06:26.557 --> 00:06:28.090 use die faces". 00:06:39.290 --> 00:06:42.610 On this expression you must see 00:06:42.777 --> 00:06:46.030 that faces is a message sent to the die class and not 00:06:46.197 --> 00:06:48.610 to an instance of die class, as it is the case 00:06:49.090 --> 00:06:51.880 in the roll method or in others methods coded until now. 00:06:52.047 --> 00:06:55.040 I will do this for you to understand when you 00:06:55.207 --> 00:06:58.900 have to use and go to the class level or not. 00:06:59.350 --> 00:07:00.710 Let's begin by writing a test. 00:07:03.050 --> 00:07:06.420 "betterInterface". 00:07:08.790 --> 00:07:10.200 If I go on with the same logic, 00:07:12.230 --> 00:07:18.080 "TestbetterCreationInterface", 00:07:18.247 --> 00:07:20.950 Here I'd like to do something like this for instance, 00:07:22.680 --> 00:07:23.640 and this to be faces. 00:07:30.620 --> 00:07:32.420 I will do it slowly. 00:07:32.950 --> 00:07:36.840 I go there and I type "instance creation", faces: , anInteger. 00:07:46.560 --> 00:07:49.000 I could write it in a short way but here 00:07:49.167 --> 00:07:50.530 I do it in a calm way. 00:07:51.000 --> 00:07:52.940 I create a die. 00:07:53.890 --> 00:07:57.740 I write "self new", as self here is the die class itself. 00:07:58.220 --> 00:08:00.410 I tell: "create an instance". 00:08:00.577 --> 00:08:03.620 And now with this instance I use 00:08:03.787 --> 00:08:08.410 an accessor to assign it the value passed as an argument. 00:08:08.577 --> 00:08:12.130 Obviously, I return the die that has just been created. 00:08:13.860 --> 00:08:16.920 When the code will be executed, it won't work because 00:08:17.087 --> 00:08:19.950 faces doesn't exist, so don't worry. 00:08:20.117 --> 00:08:22.760 You see that the test isn't ok, but 00:08:22.927 --> 00:08:27.720 it's normal, if I execute this 00:08:27.887 --> 00:08:29.520 for example, if I do debug to see... 00:08:33.640 --> 00:08:38.360 And I click on Over, here it says: "I don't know 00:08:38.527 --> 00:08:41.429 the faces message." 00:08:41.909 --> 00:08:45.770 Here we will do it calmly, I won't do it in the debugger. 00:08:46.830 --> 00:08:49.600 I say: "that's true, I have to add an accessor 00:08:52.910 --> 00:08:57.390 here. So I write faces: anInteger. 00:08:57.557 --> 00:09:01.520 And there I write : faces := anInteger. 00:09:05.020 --> 00:09:08.110 And while I'm at it, I create the read accessor. 00:09:09.330 --> 00:09:11.500 I return this one. 00:09:13.250 --> 00:09:14.450 And here my test is green. 00:09:15.240 --> 00:09:19.180 So we save, "save" 00:09:19.347 --> 00:09:22.250 "better die creation method with tests". 00:09:22.417 --> 00:09:23.050 All right. 00:09:31.610 --> 00:09:33.670 Now we can start to 00:09:33.837 --> 00:09:37.650 define what we want for 00:09:38.690 --> 00:09:42.050 diceHandle. Basically if we look, diceHandle, 00:09:42.217 --> 00:09:44.000 how would we like to write it? 00:09:44.167 --> 00:09:45.450 We would like to write diceHandle new addDie. 00:09:49.300 --> 00:09:53.290 So now we are going to create a new die, "die faces 6, addDie". 00:09:55.210 --> 00:09:59.680 "Die faces 10". 00:10:07.260 --> 00:10:12.040 We start to write a 00:10:12.207 --> 00:10:13.580 test class, this time. 00:10:15.250 --> 00:10:19.930 So a new class which inherits from TestCase. 00:10:20.290 --> 00:10:22.330 All right. I have my new tests class. 00:10:24.000 --> 00:10:26.730 And I define a test. 00:10:30.220 --> 00:10:32.850 The idea is to create a handful and to 00:10:33.017 --> 00:10:35.140 check there are the right dice in it. 00:10:35.307 --> 00:10:39.380 I write "testAdding", I want to reuse my 00:10:39.547 --> 00:10:43.730 code, there is no reason otherwise. 00:10:45.530 --> 00:10:48.060 So I have my 00:10:54.310 --> 00:10:58.940 handle; yourself , because I want to 00:10:59.107 --> 00:11:01.960 get the message receiver, it is to say the handle 00:11:02.127 --> 00:11:03.690 and not the argument that is here. 00:11:04.500 --> 00:11:08.260 Now what should I do? 00:11:08.427 --> 00:11:12.520 I write "self assert h diceNumber 00:11:13.960 --> 00:11:14.593 equals 2". 00:11:20.700 --> 00:11:23.380 I compile. Obviously the system says: "I don't 00:11:23.547 --> 00:11:25.930 know the DiceHandle variable. Do you want it 00:11:26.097 --> 00:11:26.730 to be a class?" 00:11:26.897 --> 00:11:27.960 Yes. It must be a class. 00:11:28.560 --> 00:11:29.750 Here it will define it. 00:11:29.917 --> 00:11:31.340 As I know that I have to stop the dice anyway 00:11:31.507 --> 00:11:36.440 I take this opportunity to 00:11:36.870 --> 00:11:39.580 put an instance variable. 00:11:39.747 --> 00:11:40.860 I compile all this. 00:11:41.790 --> 00:11:45.720 Now it's red because "Add die" hasn't been defined. 00:11:47.620 --> 00:11:48.570 So we will do it. 00:11:48.737 --> 00:11:51.620 Before doing this, it will be nice to initialise 00:11:54.240 --> 00:11:56.660 the handle, so we do it like this, it will prevent 00:11:56.827 --> 00:11:57.890 to have a bug later. 00:12:02.890 --> 00:12:04.560 dice : = OrderedCollection new. 00:12:04.727 --> 00:12:05.360 Recategorize. 00:12:21.880 --> 00:12:24.760 And now, I must be able to run my 00:12:24.927 --> 00:12:27.730 test, which will crash. Ok, very well. 00:12:27.897 --> 00:12:30.200 I create Add die. 00:12:30.530 --> 00:12:31.163 Adding. 00:12:35.330 --> 00:12:38.030 It says: "You should implement this method." 00:12:38.197 --> 00:12:39.080 Yes, it makes sense. 00:12:39.247 --> 00:12:42.430 I write "Dice add aDie". 00:12:43.590 --> 00:12:45.920 Ok, very good. My test won't still 00:12:46.087 --> 00:12:48.150 work because I still don't have defined the diceNumber 00:12:48.317 --> 00:12:52.120 method, let's do it. Yes, diceNumber, 00:12:52.287 --> 00:12:56.780 we will create it, in accessing this time. 00:12:57.350 --> 00:12:58.800 And diceNumber, what will it do? 00:12:58.967 --> 00:13:00.330 It must return 00:13:06.290 --> 00:13:08.110 dice size. I compile again, proceed. 00:13:09.940 --> 00:13:12.510 And my test should be green so, the tests 00:13:12.677 --> 00:13:14.860 are green and I save. 00:13:17.250 --> 00:13:18.580 "With addDie and test". 00:13:24.560 --> 00:13:28.090 We could improve the test because here 00:13:28.257 --> 00:13:31.900 it checks that we add 2 numbers, I'd like 00:13:32.067 --> 00:13:35.180 to check that when 00:13:35.347 --> 00:13:37.610 we add twice the same die we don't lose it. 00:13:38.280 --> 00:13:39.340 I write "TestAddingTwiceTheSame DieisOK". 00:13:49.040 --> 00:13:50.290 Here what do I do? 00:13:50.457 --> 00:13:54.530 I add 6 and 6 and I want to get 2 00:13:57.030 --> 00:13:59.940 I do this I run my test, it's green, super. 00:14:01.230 --> 00:14:04.700 Now, it will be nice to be able 00:14:05.880 --> 00:14:08.960 to define what it is to do 00:14:11.240 --> 00:14:14.900 add 2 dice. But before this, let's do something. 00:14:15.067 --> 00:14:17.210 If you look, what I don't like, 00:14:17.377 --> 00:14:19.030 when I inspect this for example, 00:14:23.950 --> 00:14:28.740 if I do "Inspect" here, I don't see 00:14:28.907 --> 00:14:31.530 the dice values and it's not practical to debug. 00:14:31.697 --> 00:14:33.030 In the debugger, we don't see this. 00:14:33.370 --> 00:14:36.090 So before going on, I want to improve 00:14:36.257 --> 00:14:38.370 this. I'm going to add a method 00:14:38.660 --> 00:14:41.710 in the Printing protocol. The "PrintOn" method 00:14:44.220 --> 00:14:46.840 is defined on all the objects of the system and 00:14:47.007 --> 00:14:50.380 it will convert an object to a 00:14:50.547 --> 00:14:53.490 textual representation and 00:14:55.380 --> 00:14:58.780 pass a stream. We will only precise 00:14:58.947 --> 00:15:00.420 the representation we want inside it. 00:15:01.890 --> 00:15:03.500 If I do this, I've done nothing in fact. 00:15:03.667 --> 00:15:07.630 If I do super PrintOn, in fact I've done nothing. 00:15:07.797 --> 00:15:09.230 Now I will do 00:15:09.397 --> 00:15:13.220 "aStreamnextPut", so I will put characters in the 00:15:13.387 --> 00:15:15.220 stream, but what will I put first? 00:15:16.090 --> 00:15:18.330 I will write a parenthesis with a space, maybe it 00:15:18.497 --> 00:15:19.880 will be nicer, a parenthesis. 00:15:20.450 --> 00:15:23.550 Then I will consider faces and convert them 00:15:23.717 --> 00:15:27.780 in numbers, in strings, and concatenate all this 00:15:28.360 --> 00:15:30.760 with a closing parenthesis. 00:15:31.150 --> 00:15:34.930 If I do this... I closed the debugger, so I open it again. 00:15:35.850 --> 00:15:38.630 I have the debugger. Now I have a 6-sided die 00:15:38.797 --> 00:15:40.480 and a 10-sided die. So it is much 00:15:40.647 --> 00:15:44.140 nicer, you will see, if we encounter bugs, it will help. 00:15:44.850 --> 00:15:48.140 So here I didn't do anything special, my tests are running. 00:15:49.450 --> 00:15:53.340 I save again, it doesn't cost much, "With printing". 00:15:55.220 --> 00:15:56.400 We write "with die printOn". 00:16:03.030 --> 00:16:08.000 All right. Now we create the test, we won't 00:16:08.167 --> 00:16:09.580 do it, we will go directly there. 00:16:10.080 --> 00:16:12.490 We select "add protocol", "roll", "operations". 00:16:13.600 --> 00:16:17.890 So, 00:16:18.057 --> 00:16:22.530 there are several ways to define this. 00:16:22.820 --> 00:16:25.040 I propose you one, this is not the nicest but 00:16:25.207 --> 00:16:27.160 at least it is probably the clearest for you. 00:16:27.530 --> 00:16:29.130 There is a compact way, I could 00:16:29.297 --> 00:16:31.490 do it in one line, but using iterators 00:16:31.657 --> 00:16:33.150 like "Injected to", here I'm gonna use a loop. 00:16:33.550 --> 00:16:34.210 So what do I do? 00:16:34.377 --> 00:16:36.860 I take a value that I initialize to zero. 00:16:37.390 --> 00:16:42.320 Then I do a loop on all the dice, and 00:16:42.487 --> 00:16:47.120 for each loop step I get a die, and what am 00:16:47.287 --> 00:16:47.920 I going to do with this die? 00:16:48.120 --> 00:16:51.900 I ask it to get a die roll and to add the result to 00:16:52.067 --> 00:16:53.440 my variable. 00:16:55.640 --> 00:17:00.310 Nothing very special but at least it is very very explicit. 00:17:02.000 --> 00:17:05.380 Now if I do "Inspect" and there 00:17:05.547 --> 00:17:10.510 "Roll", 5, it doesn't prove it is working. 00:17:11.210 --> 00:17:12.140 Let's try once more. 00:17:12.307 --> 00:17:13.140 11. Ok, it's working. 00:17:13.950 --> 00:17:16.119 We are gonna try to write a test, there is 00:17:16.287 --> 00:17:19.920 no reason, so we do "Test", I want to see this one 00:17:21.589 --> 00:17:22.940 and I call it rolling. 00:17:26.960 --> 00:17:30.940 So how do we have to do to test this? 00:17:31.107 --> 00:17:35.760 It has to be between one and the maximum of the number of dice. 00:17:38.000 --> 00:17:42.100 So we will do this. 00:17:42.267 --> 00:17:42.900 We 00:17:48.280 --> 00:17:49.930 could define a method doing this. 00:17:50.240 --> 00:17:53.040 Let's create a method defining the maximum. 00:17:56.720 --> 00:18:00.100 "Operation maxValue". 00:18:02.480 --> 00:18:03.240 What is maxValue ? 00:18:03.407 --> 00:18:05.020 It is very close to this. 00:18:05.780 --> 00:18:10.000 Here instead of doing roll, 00:18:11.440 --> 00:18:12.430 I will ask for the faces. 00:18:16.560 --> 00:18:20.490 Let's check. If I do "Inspect", there 00:18:21.830 --> 00:18:24.820 I do "maxValue", "16". 00:18:28.490 --> 00:18:30.480 Yes, it's right 10 and 6. 00:18:30.647 --> 00:18:33.090 So we write a test for 00:18:37.010 --> 00:18:41.600 "maxValue". So I have this, I do "maxValue equal 00:18:41.767 --> 00:18:42.400 16". 00:18:45.320 --> 00:18:48.150 So here you see, I could have coded something 00:18:48.317 --> 00:18:51.320 very dirty in my test, but finally, it is better 00:18:51.487 --> 00:18:53.690 to create a method in the class and to use it. 00:18:54.080 --> 00:18:58.370 So now, we can test the roll method 00:18:58.820 --> 00:19:02.340 works well. Let's do "roll", 00:19:05.900 --> 00:19:08.770 and say it must be comprised 00:19:08.937 --> 00:19:11.000 between... "Roll between 1 and 00:19:14.230 --> 00:19:15.690 h maxValue. 00:19:24.080 --> 00:19:26.000 If I do this, ok it works. 00:19:28.120 --> 00:19:30.870 This is not very statistical, so here we could do 00:19:31.037 --> 00:19:35.800 something like 1 000 timesRepeat. 00:19:36.000 --> 00:19:38.560 Ok. And there, 00:19:42.220 --> 00:19:46.680 we have our 1000 tests. 00:19:47.740 --> 00:19:49.330 Now we save. All right. 00:19:49.497 --> 00:19:52.440 We save once more. "save" added maxValue 00:19:54.610 --> 00:19:56.030 and roll with tests. 00:20:03.940 --> 00:20:08.380 We've almost finished, 00:20:08.547 --> 00:20:11.070 what we want to express now, is 00:20:11.237 --> 00:20:13.680 instead of having "die faces 6", 00:20:16.290 --> 00:20:17.670 I'd like to have "1 D6". 00:20:17.837 --> 00:20:18.470 And 00:20:25.510 --> 00:20:27.630 what you see at the end is that it means "send 00:20:27.797 --> 00:20:31.050 the message 6 to a small integer". 00:20:31.770 --> 00:20:34.540 So we go and look at the integer class. 00:20:34.707 --> 00:20:39.620 What we are going to do is 00:20:39.787 --> 00:20:43.660 to define a class extension. 00:20:43.827 --> 00:20:45.010 What is a class extension? 00:20:45.890 --> 00:20:50.350 I'm gonna package my methods with the same name as my package. 00:20:50.800 --> 00:20:53.360 So you will see, what do I do? I add a 00:20:53.527 --> 00:20:57.420 protocol, I put *, it must start with *dice which is 00:20:57.587 --> 00:21:00.780 my package's name, automatically this is put in grey, and 00:21:00.947 --> 00:21:02.900 it means the method will be packaged 00:21:03.067 --> 00:21:04.460 at the same time as this package. So let's do it. 00:21:04.900 --> 00:21:08.950 Let's imagine we do... What is D6? 00:21:10.000 --> 00:21:13.570 A D6... I have to think a little about it... 00:21:21.050 --> 00:21:24.250 We first create a handle because it could 00:21:24.417 --> 00:21:25.510 be 2 D6 finally. 00:21:27.210 --> 00:21:31.930 So "handle", we do "diceHandle 00:21:32.097 --> 00:21:32.730 new", 00:21:37.120 --> 00:21:38.280 ok, so I have created my thing. 00:21:39.380 --> 00:21:42.110 Now for each receiver, I will do 00:21:42.277 --> 00:21:45.430 "self", this is my integer, "timesRepeat". 00:21:46.370 --> 00:21:50.140 We will have really used a lot the timesRepeat, it's rare. 00:21:51.900 --> 00:21:54.120 "TimesRepeat handle addDie", of what? 00:21:56.790 --> 00:22:01.150 Of "die faces". And there, 00:22:02.000 --> 00:22:03.720 we know it's 6. 00:22:05.890 --> 00:22:09.830 And indeed, it would maybe be good to return the handle. 00:22:11.220 --> 00:22:12.330 So does it work? 00:22:12.497 --> 00:22:14.950 We're going to test like this and we write a test. 00:22:15.470 --> 00:22:20.380 But if I do 2 D6, Inspect, look, 00:22:20.547 --> 00:22:22.390 I do have 2 D6. So that's cool. 00:22:23.190 --> 00:22:24.290 Let's write the test. 00:22:25.640 --> 00:22:27.140 We will categorize those tests after all. 00:22:28.150 --> 00:22:29.330 We write "testNewSyntax". 00:22:33.950 --> 00:22:36.420 Here for the moment we only have D6, we will generalize later. 00:22:38.010 --> 00:22:40.000 We want to do exactly the same thing 00:22:40.167 --> 00:22:44.440 than this, so we will have an handle, let's say 2 D6. 00:22:47.020 --> 00:22:49.620 And there, we do "selfAssert". 00:22:53.310 --> 00:22:54.430 What could we test? 00:22:54.597 --> 00:22:56.470 That diceNumber equals 2 00:23:02.880 --> 00:23:05.420 for instance. So you've noticed sometimes I use 00:23:05.587 --> 00:23:09.160 diceHandle, I could have also used = 2 here. 00:23:09.810 --> 00:23:12.080 In general, it is nicer to use assert equal 00:23:12.540 --> 00:23:14.310 because like this, when there is an error, the system 00:23:14.477 --> 00:23:18.020 says: "I've received this and got this value instead of..." 00:23:18.630 --> 00:23:22.910 If I write =, it will say: "I've got a wrong expression." 00:23:23.680 --> 00:23:26.480 Here for the final user, who is yourself, 00:23:26.647 --> 00:23:28.850 as a developer, it is better to use 00:23:30.580 --> 00:23:33.340 assert equals because it will say: "I've received 3 whereas 00:23:33.560 --> 00:23:34.680 I was expecting 2", for instance. 00:23:35.860 --> 00:23:37.060 So here, I do this. 00:23:37.510 --> 00:23:38.780 Ok, it works. 00:23:39.320 --> 00:23:41.940 Could we have a smarter 00:23:42.107 --> 00:23:43.090 version of this test? 00:23:43.257 --> 00:23:44.240 For the moment, it suits us. 00:23:44.860 --> 00:23:46.640 You see that now in 00:23:46.807 --> 00:23:50.200 the package, I have an extension called D6. 00:23:50.690 --> 00:23:55.480 We will generalize this with 00:23:56.120 --> 00:23:57.550 "aNumberOfFaces" 00:24:01.360 --> 00:24:03.870 So "aNumberOfFaces", we put it there. 00:24:05.200 --> 00:24:08.000 And we rewrite D6 because it would be better. 00:24:08.137 --> 00:24:12.580 We write D6 like this. We do 00:24:12.747 --> 00:24:16.660 returns self D6. 00:24:19.050 --> 00:24:20.750 We do all the other ones. 00:24:20.917 --> 00:24:24.370 We do 4, 00:24:26.020 --> 00:24:30.870 2. It's more a coin than a die, but 2, 00:24:31.220 --> 00:24:35.640 10 and 20. 00:24:36.440 --> 00:24:37.570 You've understood the principle. 00:24:41.540 --> 00:24:45.930 So let's run the tests, as we've changed the implementation. 00:24:47.010 --> 00:24:49.370 2 D6... it means it works. 00:24:49.830 --> 00:24:50.690 So let's save. 00:24:59.670 --> 00:25:03.320 What is there still to do? 00:25:03.680 --> 00:25:08.030 In fact, we have still to be able to add the handles. 00:25:09.300 --> 00:25:11.600 What tests do I want? 00:25:11.767 --> 00:25:14.640 For instance, I want to be sure if I do 00:25:18.710 --> 00:25:23.240 "addingHandles", 00:25:23.407 --> 00:25:25.590 (I can use the new syntax, 00:25:25.757 --> 00:25:26.440 so it's nice) 00:25:26.960 --> 00:25:28.940 I want to test that if 00:25:29.107 --> 00:25:33.820 I write 2 D20 + 3 D5 00:25:34.000 --> 00:25:38.570 or 3 D6 instead (don't start to complicate 00:25:38.737 --> 00:25:42.050 things). How much should I get ? 00:25:43.160 --> 00:25:46.770 diceNumber should be equal to 5. 00:25:48.180 --> 00:25:52.270 So here you see that we have to define the + operator. 00:25:52.870 --> 00:25:55.520 In Pharo + isn't an operator, it's just a message. 00:25:55.687 --> 00:25:59.230 So we define a message on the DiceHandle class. 00:26:00.530 --> 00:26:02.850 We write +. 00:26:04.650 --> 00:26:05.520 So "aDiceHandle". 00:26:07.530 --> 00:26:09.410 Now we can wonder if 00:26:09.577 --> 00:26:11.770 we modify the receiver or either if we use 00:26:11.937 --> 00:26:12.840 a functional approach. 00:26:13.130 --> 00:26:14.740 I prefer to use a functional approach 00:26:14.907 --> 00:26:17.470 in which we create a new handle. 00:26:20.180 --> 00:26:23.690 So I'm gonna create a new handle, I write 00:26:26.060 --> 00:26:27.650 "handle self class new". 00:26:29.540 --> 00:26:34.060 Here I avoided to write diceHandle and later there 00:26:34.227 --> 00:26:36.360 will be a lesson explaining why. 00:26:36.527 --> 00:26:37.770 I prefer, it's closer. 00:26:37.937 --> 00:26:39.800 In general you don't hard-code the classes' name. 00:26:40.430 --> 00:26:42.530 You will see it in week 7 or something like this, 00:26:42.697 --> 00:26:44.040 there is a complete explanation. 00:26:44.740 --> 00:26:49.660 If I do "self dice do", I 00:26:49.827 --> 00:26:53.480 iterate on my dice and I add them in handle. 00:26:53.647 --> 00:26:55.610 So I do "handle addDie each", 00:26:59.780 --> 00:27:03.660 and I do the same... Here I don't 00:27:03.827 --> 00:27:05.720 need self and in fact I don't know 00:27:05.887 --> 00:27:07.420 the message, that's what it was telling me, and 00:27:07.587 --> 00:27:09.370 it makes me notice that, indeed, I haven't defined it 00:27:09.820 --> 00:27:12.790 and it hasn't worked for "diceHandle", but 00:27:15.630 --> 00:27:20.480 no matter, let's compile first and we'll fix it later. 00:27:21.230 --> 00:27:22.450 So here, what does it mean? 00:27:22.617 --> 00:27:24.790 It means it lacks an accessor, dice. 00:27:25.280 --> 00:27:28.770 So we add dice here, dice returns 00:27:28.937 --> 00:27:32.060 the collection of my dice. 00:27:32.227 --> 00:27:35.280 Now I'm gonna test, see if my test is ok. 00:27:35.700 --> 00:27:38.690 My test is ok, it's super, it means I have 00:27:38.857 --> 00:27:43.610 almost finished, I save, "with handles 00:27:44.810 --> 00:27:46.690 additions". Ok, all right. 00:27:49.820 --> 00:27:53.770 It means now we can write 00:27:57.300 --> 00:28:02.210 2 D4 and we 00:28:02.377 --> 00:28:06.380 can do "Roll", and it returns a number. 00:28:08.000 --> 00:28:10.400 Now you are ready to play "Dungeons and Dragons". 00:28:11.200 --> 00:28:15.870 What you have to know: we defined 00:28:17.570 --> 00:28:19.480 our methods, we defined our tests, we run 00:28:19.647 --> 00:28:23.010 them, we extended a system class, 00:28:23.177 --> 00:28:27.000 the integer class, with extensions linked to our 00:28:27.167 --> 00:28:30.590 package, which will only be visible when our package will be loaded. 00:28:32.290 --> 00:28:34.580 We also overloaded operators, but 00:28:34.747 --> 00:28:39.320 in fact we only defined a new + message, because 00:28:39.487 --> 00:28:43.600 in Pharo the addition is just another message, 00:28:43.767 --> 00:28:48.160 this enabled us to express quite easily a nice DSL. 00:28:49.900 --> 00:28:50.850 So now it's your turn to code!