Would you like to inspect the original subtitles? These are the user uploaded subtitles that are being translated:
1
00:00:00,000 --> 00:00:07,880
Now, if there's one thing you're going to see everywhere in Ruby programs, it's blocks.
2
00:00:07,880 --> 00:00:10,040
So it's time that we learn a little bit more about them.
3
00:00:10,040 --> 00:00:12,640
Now, we're already using them in our program.
4
00:00:12,640 --> 00:00:16,140
We're using blocks here in our test to organize code.
5
00:00:16,140 --> 00:00:20,280
And in our playlist, we're using blocks to iterate through an array.
6
00:00:20,280 --> 00:00:23,160
Now you'll find blocks everywhere in good Ruby programs.
7
00:00:23,160 --> 00:00:27,400
Yeah, and many of the methods in the Ruby standard library also take blocks.
8
00:00:27,400 --> 00:00:31,939
So to become an effective Ruby programmer, you really need to get comfortable with blocks.
9
00:00:31,939 --> 00:00:35,280
So we're going to look at a number of ways to use them in this section.
10
00:00:35,280 --> 00:00:39,440
In our movies, we'll use blocks to iterate through a number of movie viewings.
11
00:00:39,440 --> 00:00:42,800
And then you'll use them to iterate through a number of game rounds.
12
00:00:42,800 --> 00:00:46,239
We'll also partition out hits versus flops with blocks.
13
00:00:46,239 --> 00:00:49,440
And then you'll partition out strong from wimpy players.
14
00:00:49,440 --> 00:00:52,800
Finally, blocks will help us sort the movies by rank.
15
00:00:52,800 --> 00:00:56,060
And then you'll use them to sort the players by score.
16
00:00:56,060 --> 00:00:57,680
So let's start with some simple blocks.
17
00:00:57,680 --> 00:01:02,000
Sure, we've seen that blocks are just chunks of code, and they come either between braces
18
00:01:02,000 --> 00:01:03,120
or between do and end.
19
00:01:03,120 --> 00:01:04,760
So let's try a couple.
20
00:01:04,760 --> 00:01:08,560
So let's just start with a really simple single line block.
21
00:01:08,560 --> 00:01:11,440
We'll just use put as and echo.
22
00:01:11,440 --> 00:01:13,080
And so this is just a code block.
23
00:01:13,080 --> 00:01:15,440
It comes between curly braces.
24
00:01:15,440 --> 00:01:17,320
But by itself, we can't really do anything with it.
25
00:01:17,320 --> 00:01:18,760
We can't run a block.
26
00:01:18,760 --> 00:01:21,880
A block needs to be associated with a method call.
27
00:01:21,880 --> 00:01:25,160
So let's associate it with the call to the times method.
28
00:01:25,160 --> 00:01:28,179
So three dot times, we want it to run this block.
29
00:01:28,179 --> 00:01:29,179
We run that.
30
00:01:29,179 --> 00:01:30,920
We're at the Grand Canyon.
31
00:01:30,920 --> 00:01:33,520
Echo, echo, echo.
32
00:01:33,520 --> 00:01:36,880
OK, so that's just a single line block right there.
33
00:01:36,880 --> 00:01:39,399
Now sometimes you want to do more than one thing.
34
00:01:39,399 --> 00:01:43,759
And so blocks can also come between do and end, like that.
35
00:01:43,759 --> 00:01:47,800
So let's say we want to do something like we want to print out sit up, and then we'll
36
00:01:47,800 --> 00:01:52,199
print out push up, and then we'll print out chin up.
37
00:01:52,199 --> 00:01:53,199
Right?
38
00:01:53,200 --> 00:01:55,160
And in the same way, this block won't run by itself.
39
00:01:55,160 --> 00:01:56,400
We need to associate it with a method.
40
00:01:56,400 --> 00:01:58,560
So let's say we do this 10 times.
41
00:01:58,560 --> 00:02:01,960
We want it to run this block of code.
42
00:02:01,960 --> 00:02:02,960
So there we go.
43
00:02:02,960 --> 00:02:05,440
We've got our exercise program all implemented here.
44
00:02:05,440 --> 00:02:09,539
It printed out each of those strings as it looped through the block.
45
00:02:09,539 --> 00:02:12,440
Now just like a method, blocks can also take parameters.
46
00:02:12,440 --> 00:02:15,480
And block parameters come between these vertical bars.
47
00:02:15,480 --> 00:02:17,400
Some people call them goal posts.
48
00:02:17,400 --> 00:02:20,840
And we just give it the variable name, the block parameter variable.
49
00:02:20,840 --> 00:02:22,140
We'll call this number.
50
00:02:22,140 --> 00:02:27,239
And when a block parameter is here on the times method, times will assign to that number
51
00:02:27,239 --> 00:02:28,760
each iteration number.
52
00:02:28,760 --> 00:02:32,480
So if we then use the number inside of the block, let's say we use number right there
53
00:02:32,480 --> 00:02:33,480
to print out the number of sit ups.
54
00:02:33,480 --> 00:02:34,480
I'm just going to take that.
55
00:02:34,480 --> 00:02:37,519
I'm going to paste it down here.
56
00:02:37,519 --> 00:02:41,720
If we run this code, well, we see that it prints out the number.
57
00:02:41,720 --> 00:02:44,399
Zero sit up, one sit up, and so on.
58
00:02:44,399 --> 00:02:46,160
So that's just a block parameter.
59
00:02:46,160 --> 00:02:48,600
It gets assigned as times is running.
60
00:02:48,600 --> 00:02:52,640
And assigns each iteration into that variable.
61
00:02:52,640 --> 00:02:55,640
As we've seen before, these block parameters are local to the block.
62
00:02:55,640 --> 00:02:59,959
So if we come down here and we try to print out number, well, we're going to get an error
63
00:02:59,959 --> 00:03:01,200
at the bottom.
64
00:03:01,200 --> 00:03:04,160
Undefined local variable or method number.
65
00:03:04,160 --> 00:03:06,180
Because block parameters are local to the block.
66
00:03:06,180 --> 00:03:09,079
So we can't access them outside of the block.
67
00:03:09,079 --> 00:03:12,519
Now sometimes these methods that we associate the block with take parameters.
68
00:03:12,519 --> 00:03:17,160
For example, if we had the, let's see, let's take this and let's change it over to the
69
00:03:17,160 --> 00:03:18,380
up to method.
70
00:03:18,380 --> 00:03:23,000
The up to method takes a parameter and it's the maximum number to go to, let's say 10.
71
00:03:23,000 --> 00:03:27,720
So here's the method name, here's the method parameter, and then the block comes after
72
00:03:27,720 --> 00:03:29,940
the method name and the parameter.
73
00:03:29,940 --> 00:03:34,880
So in this case, if we run it, we should start at 1 and go up to 10.
74
00:03:34,880 --> 00:03:37,260
Because before we started at 0 and went up to 9.
75
00:03:37,260 --> 00:03:41,840
And up to lets us bound that in a lower and an upper range.
76
00:03:41,840 --> 00:03:44,800
So let's recap the various block forms we've seen.
77
00:03:44,800 --> 00:03:46,640
Here we call the times method.
78
00:03:46,640 --> 00:03:49,279
It takes a block which is simply a chunk of code.
79
00:03:49,279 --> 00:03:54,320
In this case, because it's a single line block, we surround the block code with braces.
80
00:03:54,320 --> 00:03:57,399
The block is associated with the call to the times method.
81
00:03:57,399 --> 00:04:03,160
So in this case, times invokes the block, wait for it, three times.
82
00:04:03,160 --> 00:04:09,000
Now if you have a multi-line block, the convention is to use do and end instead of braces.
83
00:04:09,000 --> 00:04:13,959
And in this example, we used a block parameter, the number variable, to capture the iteration
84
00:04:13,959 --> 00:04:14,980
number.
85
00:04:14,980 --> 00:04:17,740
We refer to that variable within the block.
86
00:04:17,740 --> 00:04:22,760
In the next example, we use the up to method which takes a parameter, the maximum number.
87
00:04:22,760 --> 00:04:25,960
The block then comes after the method name and its parameters.
88
00:04:25,960 --> 00:04:30,539
Finally, we've seen that the each method can take a block too.
89
00:04:30,539 --> 00:04:34,180
Now methods like times, up to, and each act like a loop.
90
00:04:34,180 --> 00:04:36,680
They invoke a block of code repeatedly.
91
00:04:36,680 --> 00:04:39,120
And we sometimes refer to them as iterators.
92
00:04:39,120 --> 00:04:42,700
Now in other programming languages, you might be used to more primitive looping constructs
93
00:04:42,700 --> 00:04:44,740
like while and for loops.
94
00:04:44,740 --> 00:04:50,000
But it's more idiomatic in Ruby to call iterator methods and pass them a block.
95
00:04:50,000 --> 00:04:53,080
So let's put some blocks to work in our movie example.
96
00:04:53,080 --> 00:04:56,320
You know, right now our play method, it just plays each movie once.
97
00:04:56,320 --> 00:04:58,640
But what if we wanted to have a movie marathon?
98
00:04:58,640 --> 00:05:02,680
Well, we could just change the play method to take a parameter which would be the number
99
00:05:02,680 --> 00:05:04,760
of times we want to play all the movies.
100
00:05:04,760 --> 00:05:08,360
So over in our play method here, we want to just change this so we iterate through the
101
00:05:08,360 --> 00:05:11,760
movies and we play them all some iteration number of times.
102
00:05:11,760 --> 00:05:12,760
So let's just start really simple.
103
00:05:12,760 --> 00:05:15,960
Let's just try three dot times do.
104
00:05:15,960 --> 00:05:19,420
And the body of the block is going to be this inner loop.
105
00:05:19,420 --> 00:05:21,640
So we're actually going to end up with a loop inside of a loop.
106
00:05:21,640 --> 00:05:24,719
We're going to iterate three times and every time through the loop, then we're going to
107
00:05:24,719 --> 00:05:28,440
iterate through all the movies and have them reviewed and played.
108
00:05:28,440 --> 00:05:32,840
So if we just go out to our flix file and we run this now.
109
00:05:32,840 --> 00:05:36,460
Well, the movies are getting played three times, but it's really kind of hard to see
110
00:05:36,460 --> 00:05:38,880
which viewing number we're looking at.
111
00:05:38,880 --> 00:05:40,400
So let's change that around a little bit.
112
00:05:40,400 --> 00:05:42,599
Back over in our playlist.
113
00:05:42,600 --> 00:05:48,120
Instead of using three dot times, let's actually pass in a number here.
114
00:05:48,120 --> 00:05:54,200
We'll just say this is the number of viewings and we're going to change it to viewings times.
115
00:05:54,200 --> 00:05:58,200
And then we'll actually capture the current count as a block parameter there.
116
00:05:58,200 --> 00:06:05,600
And then inside of here, we can print out, we'll just put a new line viewing and we'll
117
00:06:05,600 --> 00:06:06,600
print out the count.
118
00:06:06,600 --> 00:06:09,040
That way we'll know the viewing number.
119
00:06:09,040 --> 00:06:12,700
And then because we changed the play method to take a parameter, we've got to go back
120
00:06:12,700 --> 00:06:13,920
over to our flix file here.
121
00:06:13,920 --> 00:06:17,800
And when I call play, I'll just pass in, I'll just pass in three this time.
122
00:06:17,800 --> 00:06:19,040
So we get three iterations.
123
00:06:19,040 --> 00:06:20,920
Go ahead and run that.
124
00:06:20,920 --> 00:06:22,760
And we see that we've got Kermit's playlist.
125
00:06:22,760 --> 00:06:24,680
This is just the setup at the top.
126
00:06:24,680 --> 00:06:27,800
Viewing zero, viewing one and viewing two.
127
00:06:27,800 --> 00:06:31,160
So all the movies are getting viewed three times.
128
00:06:31,160 --> 00:06:32,320
Hmm.
129
00:06:32,320 --> 00:06:35,520
But it starts counting at zero.
130
00:06:35,520 --> 00:06:37,040
That may not be what we want.
131
00:06:37,040 --> 00:06:40,000
Yeah, let's tidy that up just a little bit.
132
00:06:40,000 --> 00:06:41,000
We'll close that down.
133
00:06:41,000 --> 00:06:43,560
We'll go back over to our playlist.
134
00:06:43,560 --> 00:06:49,000
Instead of using times, we could just use one up to, and we'll use viewings as the maximum
135
00:06:49,000 --> 00:06:50,000
number there.
136
00:06:50,000 --> 00:06:52,440
So then it'll start at one and go to whatever number.
137
00:06:52,440 --> 00:06:54,080
So it should start at one and go to three.
138
00:06:54,080 --> 00:06:57,520
I've got to run the flix file there.
139
00:06:57,520 --> 00:06:58,520
There we go.
140
00:06:58,520 --> 00:07:00,120
Viewing one, viewing two and viewing three.
141
00:07:00,120 --> 00:07:01,120
That's better.
142
00:07:01,120 --> 00:07:05,440
So now that the movie marathon is over and Waldorf and Stahler have seen the movies three
143
00:07:05,440 --> 00:07:08,360
times, it would be nice to know what they thought.
144
00:07:08,360 --> 00:07:10,760
It would be nice to separate the hits from the flops.
145
00:07:10,760 --> 00:07:12,960
Yeah, now we could do this the long way.
146
00:07:12,960 --> 00:07:16,920
We could just iterate through all the movies and then use a conditional to determine whether
147
00:07:16,920 --> 00:07:18,160
it was a hit or a flop.
148
00:07:18,160 --> 00:07:19,160
Right.
149
00:07:19,160 --> 00:07:22,200
But Ruby has some other built-in iterator methods that makes this sort of list processing
150
00:07:22,200 --> 00:07:23,200
a lot easier.
151
00:07:23,200 --> 00:07:24,200
Right.
152
00:07:24,200 --> 00:07:27,080
So to look at that, let's start with a simple list of numbers.
153
00:07:27,080 --> 00:07:28,080
Sure.
154
00:07:28,080 --> 00:07:30,880
So over an IRB, I'll just create a variable to hold our numbers, and we want this to be
155
00:07:30,880 --> 00:07:31,880
an array.
156
00:07:31,880 --> 00:07:35,200
I could use one, two, three, four.
157
00:07:35,200 --> 00:07:38,159
Well that will create an array, but there's actually an easier way to create an array
158
00:07:38,159 --> 00:07:39,440
of numbers.
159
00:07:39,440 --> 00:07:43,400
We can set numbers equal to, we'll use a range.
160
00:07:43,400 --> 00:07:44,920
We'll say one dot dot ten.
161
00:07:44,920 --> 00:07:46,000
That's a range in Ruby.
162
00:07:46,000 --> 00:07:49,520
We can call the two underscore a method, which will convert it to an array.
163
00:07:49,520 --> 00:07:51,480
Now I've got a nice array of ten numbers.
164
00:07:51,480 --> 00:07:52,480
Okay.
165
00:07:52,480 --> 00:07:56,599
So let's say we wanted to select all the numbers that were greater than five.
166
00:07:56,599 --> 00:08:01,039
Well, the way to do that is instead of using each to iterate through, we can use the method
167
00:08:01,039 --> 00:08:03,280
select on an array.
168
00:08:03,280 --> 00:08:04,620
Select takes a block.
169
00:08:04,620 --> 00:08:09,720
So it's going to be a single line block, so I'm just going to put it between braces there.
170
00:08:09,720 --> 00:08:11,280
Select gives us each element.
171
00:08:11,280 --> 00:08:14,840
I'm going to say it's going to be a block parameter called in, and then I'm just going
172
00:08:14,840 --> 00:08:18,320
to say I want all the numbers greater than five.
173
00:08:18,320 --> 00:08:22,580
So what this does is it loops through all the numbers for us, hands us each number,
174
00:08:22,580 --> 00:08:23,920
and then we have the condition in here.
175
00:08:23,920 --> 00:08:29,400
We say we want a new array where all the elements are only those that are greater than five.
176
00:08:29,400 --> 00:08:33,240
So if we run that, we get numbers greater than five.
177
00:08:33,240 --> 00:08:37,460
Now this syntax may look a little cryptic, but don't let it throw you.
178
00:08:37,460 --> 00:08:39,320
Let's look at this a different way.
179
00:08:39,320 --> 00:08:44,400
We could also select all the numbers greater than five by using a do in block style, but
180
00:08:44,400 --> 00:08:48,280
since it's a single line of code, we can write it all on one line.
181
00:08:48,280 --> 00:08:53,560
Then we can replace the do and in with curly braces, and then we can further simplify it
182
00:08:53,560 --> 00:08:57,700
by replacing number with a single character n.
183
00:08:57,700 --> 00:09:00,560
And this gives us a really elegant line of code.
184
00:09:00,560 --> 00:09:01,880
So there's no magic here.
185
00:09:01,880 --> 00:09:03,280
It's just different syntax.
186
00:09:03,280 --> 00:09:07,720
Yeah, and it's also fairly idiomatic in Ruby to write lines of code that look just like
187
00:09:07,720 --> 00:09:08,720
this.
188
00:09:08,720 --> 00:09:10,840
So let's have a look at a couple more examples.
189
00:09:10,840 --> 00:09:14,120
Let's say we wanted to get all the even numbers out of our numbers array here.
190
00:09:14,120 --> 00:09:19,200
So if we have our numbers array, we can call the select method that we've seen before.
191
00:09:19,200 --> 00:09:23,460
We're going to get each element passed in in the block parameter in, and then numbers
192
00:09:23,460 --> 00:09:27,200
have a method called even, so I can just call even question mark.
193
00:09:27,200 --> 00:09:29,560
That's going to return true or false.
194
00:09:29,560 --> 00:09:32,920
For all the elements where it's true, they're going to get put into a new array, and that
195
00:09:32,920 --> 00:09:35,599
array is going to get assigned to the variable evens.
196
00:09:35,599 --> 00:09:37,160
So we print that out.
197
00:09:37,160 --> 00:09:40,160
Sure enough, we've got all of our evens in an array.
198
00:09:40,160 --> 00:09:41,760
So how about all the odd numbers now?
199
00:09:41,760 --> 00:09:46,040
Well, the difference here is we want to call the odd method on our numbers.
200
00:09:46,040 --> 00:09:50,760
There's an odd question mark method, and we'll assign that to the variable odds.
201
00:09:50,760 --> 00:09:52,520
So there we've got all of our odds that way.
202
00:09:52,520 --> 00:09:55,920
Now another way to get the odds would be to do something like this.
203
00:09:55,920 --> 00:09:59,680
The same thing that we did for the evens, but instead of selecting all the evens, we
204
00:09:59,680 --> 00:10:05,040
could reject all the evens like that, and this would be the same as getting the odds.
205
00:10:05,040 --> 00:10:09,719
Finally, if we wanted to just partition out the evens and the odds, there's a sort of
206
00:10:09,719 --> 00:10:11,819
handy way to do this in one fell swoop.
207
00:10:11,819 --> 00:10:13,959
We can just say numbers partition.
208
00:10:13,959 --> 00:10:18,959
We're going to give that a block as well, and then we're going to partition.
209
00:10:18,959 --> 00:10:21,219
We're going to say in dot even.
210
00:10:21,219 --> 00:10:25,520
And notice here that we have two variables on the left-hand side, evens and odds.
211
00:10:25,520 --> 00:10:29,480
For the array that matches the evens, it's going to assign that array over to the evens
212
00:10:29,480 --> 00:10:34,560
variable, and for everything else, it's going to put it into an array and assign it to the
213
00:10:34,560 --> 00:10:35,560
odds variable.
214
00:10:35,560 --> 00:10:39,040
So if we run that, notice that we get a nested array.
215
00:10:39,040 --> 00:10:45,040
We've got this array here and this array here, and it's nested inside of a larger array on
216
00:10:45,040 --> 00:10:46,040
the outside.
217
00:10:46,040 --> 00:10:50,380
So we've got a nested array, but Ruby's smart enough when that nested array gets returned
218
00:10:50,380 --> 00:10:54,920
from this partition method, it destructures it into two separate variables.
219
00:10:54,920 --> 00:10:59,880
So if we look at evens, it's just the array of evens, and odds is the array of odds.
220
00:10:59,880 --> 00:11:03,040
Finally, let's say that we wanted to add up all of these numbers.
221
00:11:03,040 --> 00:11:07,800
Well, there's another iterator method that's really handy to use, and it's the reduce method.
222
00:11:07,800 --> 00:11:11,699
And what it does is it reduces an array down to a scalar value.
223
00:11:11,699 --> 00:11:13,880
So let's say we wanted to reduce this array.
224
00:11:13,880 --> 00:11:15,699
It takes a block.
225
00:11:15,699 --> 00:11:19,439
In this particular case, it's going to give two block parameters.
226
00:11:19,439 --> 00:11:23,680
The first one's going to be a variable that's used as an accumulator of values, and the
227
00:11:23,680 --> 00:11:26,859
second one is actually the element.
228
00:11:26,859 --> 00:11:30,719
And then inside of the block, we can take sum and add it to n.
229
00:11:30,719 --> 00:11:35,160
So what's going to happen here is the first time through this loop, sum is going to get
230
00:11:35,160 --> 00:11:40,160
assigned to the first number, which is going to be 1, and then we're going to say sum plus
231
00:11:40,160 --> 00:11:45,040
n, so we're going to take 1 plus 2 and assign that back to sum.
232
00:11:45,040 --> 00:11:49,000
So sum is going to be 1, then it's going to be 3, then it's going to be 6.
233
00:11:49,000 --> 00:11:55,600
So that lets us accumulate values, and we end up with the total of all these numbers being 55.
234
00:11:55,600 --> 00:11:57,720
So reduce takes this block syntax.
235
00:11:57,720 --> 00:12:02,060
It also takes a slightly different syntax.
236
00:12:02,060 --> 00:12:05,840
We can pass in a symbol with the name of a particular operator.
237
00:12:05,840 --> 00:12:09,000
In this case, we want to add all those numbers together.
238
00:12:09,000 --> 00:12:13,320
So we use a symbol and a plus, and it's just going to apply that operator to all the elements
239
00:12:13,320 --> 00:12:16,960
in the array and reduce them down to some value, which would be 55.
240
00:12:16,960 --> 00:12:21,300
So if we wanted to multiply all the numbers, we'd use the symbol and the times method.
241
00:12:21,300 --> 00:12:25,240
You may see reduce, there's a synonym for it called inject, so that's often used in
242
00:12:25,240 --> 00:12:30,120
Ruby as well, and we'll see reduce again later on in the course.
243
00:12:30,120 --> 00:12:31,920
Okay now, so back to our movie.
244
00:12:31,920 --> 00:12:35,920
Let's use partition to separate the hits from the flops like we did with numbers.
245
00:12:35,920 --> 00:12:38,360
Sure, and we'll actually do that in a new method.
246
00:12:38,360 --> 00:12:41,760
We'll write a method called printStats, and we'll just do the hits and the flops for now,
247
00:12:41,760 --> 00:12:44,520
but later on we'll put some more statistics in there for the game.
248
00:12:44,520 --> 00:12:45,680
Perfect.
249
00:12:45,680 --> 00:12:49,640
So back over in our playlist class, I want a method called printStats.
250
00:12:49,640 --> 00:12:53,520
I'm just going to give us some room here.
251
00:12:53,520 --> 00:12:55,640
PrintStats, like that.
252
00:12:55,640 --> 00:13:03,160
And then I'm just going to start it off by printing out that we have the names, stats,
253
00:13:03,160 --> 00:13:05,880
just like that, so we know which movie name we're doing.
254
00:13:05,880 --> 00:13:08,520
And then we want to partition the hits from the flops, so I'm going to have the hits,
255
00:13:08,520 --> 00:13:10,099
I'm going to have the flops.
256
00:13:10,099 --> 00:13:12,359
That's going to be our movies array.
257
00:13:12,360 --> 00:13:15,720
We're going to partition it, just like we saw in IRB.
258
00:13:15,720 --> 00:13:18,360
It's going to hand us each movie object.
259
00:13:18,360 --> 00:13:22,440
And then to partition it, remember that we have that hit question mark method that returns
260
00:13:22,440 --> 00:13:24,560
true or false as to whether the movie's a hit or not.
261
00:13:24,560 --> 00:13:26,640
So we can just call movie.hit.
262
00:13:26,640 --> 00:13:30,280
All the ones that match that criteria will end up in the hits array.
263
00:13:30,280 --> 00:13:33,260
All the ones that don't will end up in the flops array.
264
00:13:33,260 --> 00:13:35,160
So we'll just print that out.
265
00:13:35,160 --> 00:13:40,120
We'll say the hits, and then we can print out hits.
266
00:13:40,120 --> 00:13:44,760
And when we call putS on an array, it's going to call the toS method on each of those elements,
267
00:13:44,760 --> 00:13:47,720
and we've got a toS method in movies, so that should work.
268
00:13:47,720 --> 00:13:51,920
And then I'm going to print out the flops down beneath that.
269
00:13:51,920 --> 00:13:54,400
Put us the flops, just like that.
270
00:13:54,400 --> 00:13:58,480
Then we need to call this method, so I need to go back over into flix.rb.
271
00:13:58,480 --> 00:14:03,480
After we've played everything, we take our playlist and we call the printStats method.
272
00:14:03,480 --> 00:14:05,200
Let's give this a go.
273
00:14:05,200 --> 00:14:08,160
We've got all of our viewings.
274
00:14:08,160 --> 00:14:09,160
Look down at the bottom.
275
00:14:09,160 --> 00:14:10,160
We've got the determineStats.
276
00:14:10,160 --> 00:14:14,240
And in this case, we've got one hit and two flops.
277
00:14:14,240 --> 00:14:16,959
Oh, Goldfinger really took a hit.
278
00:14:16,959 --> 00:14:19,640
Wow, it's in the tank.
279
00:14:19,640 --> 00:14:20,640
Negative one rank.
280
00:14:20,640 --> 00:14:21,640
Let's just try that one more time.
281
00:14:21,640 --> 00:14:27,120
Well, Goldfinger did even worse that time.
282
00:14:27,120 --> 00:14:28,880
But we've got them partitioned out.
283
00:14:28,880 --> 00:14:33,520
So as we run more iterations, we'll see sort of different behavior there.
284
00:14:33,520 --> 00:14:36,880
Now the last thing we want to do with a block is sort the movies.
285
00:14:36,880 --> 00:14:41,200
Right now when we print our movies, it prints them in the order we added them to the playlist.
286
00:14:41,200 --> 00:14:42,200
Let's look at that.
287
00:14:42,200 --> 00:14:43,200
You're right.
288
00:14:43,200 --> 00:14:46,120
Right now we're adding movie1, movie2, movie3 in that order.
289
00:14:46,120 --> 00:14:50,200
If we were to reverse the order, let's say we add Goldfinger second there and then we
290
00:14:50,200 --> 00:14:51,720
run the thing.
291
00:14:51,720 --> 00:14:56,000
Well, Goonies gets played first, then Goldfinger, and then Ghostbusters.
292
00:14:56,000 --> 00:14:59,760
So it's playing them in the order that we added them to the array.
293
00:14:59,760 --> 00:15:01,640
So let's step back and look at some basic sorting.
294
00:15:01,640 --> 00:15:04,960
I've just got this sorting.rb file here so we can play around with it.
295
00:15:04,960 --> 00:15:09,820
So let's say we have this array of names, Goonies, Ghostbusters, Goldfinger, and Godfather.
296
00:15:09,820 --> 00:15:14,440
Now if we do the default sorting, we can just print out names.sort, sort as a method on
297
00:15:14,440 --> 00:15:15,520
all arrays.
298
00:15:15,520 --> 00:15:19,480
And if we were to run that, well we're going to get them in alphabetical order.
299
00:15:19,480 --> 00:15:20,980
Goonies is last.
300
00:15:20,980 --> 00:15:25,100
So that's basically the built-in sorting for characters or strings.
301
00:15:25,100 --> 00:15:26,880
We can also do some custom sorting.
302
00:15:26,880 --> 00:15:28,720
Let's say we wanted to change this.
303
00:15:28,720 --> 00:15:32,720
We could use the sort by method and then we can pass it in some criteria.
304
00:15:32,720 --> 00:15:34,160
And that takes a block.
305
00:15:34,160 --> 00:15:35,400
It gives us each string.
306
00:15:35,400 --> 00:15:38,180
I'll call this w because it represents sort of a word.
307
00:15:38,180 --> 00:15:42,140
And so let's say we wanted to order them by their length, for example.
308
00:15:42,140 --> 00:15:43,959
So we just call the length method.
309
00:15:43,959 --> 00:15:46,480
Remember that's a string and strings have a length method on them.
310
00:15:46,480 --> 00:15:52,319
So if we run this, then we get them in ascending order from the smallest word there to the
311
00:15:52,319 --> 00:15:53,800
longest word, Ghostbusters.
312
00:15:53,800 --> 00:15:56,680
Okay, now let's try some of that with our movie object.
313
00:15:56,680 --> 00:15:57,680
So I'm just going to remove this.
314
00:15:57,680 --> 00:16:01,040
I'm going to require our movie class there.
315
00:16:01,040 --> 00:16:05,839
And let's just see what happens if we have, let's just create a couple movies real quick.
316
00:16:05,839 --> 00:16:06,839
Goonies will be 10.
317
00:16:06,839 --> 00:16:10,640
We'll have movie two will be, let's see.
318
00:16:10,640 --> 00:16:13,319
Let's do Godfather with three.
319
00:16:13,319 --> 00:16:14,319
With a rank of three?
320
00:16:14,319 --> 00:16:15,319
Yeah.
321
00:16:15,319 --> 00:16:16,319
Okay.
322
00:16:16,319 --> 00:16:18,439
And let's do Goldfinger.
323
00:16:18,439 --> 00:16:21,719
We'll split the difference and do seven.
324
00:16:21,719 --> 00:16:24,120
Goldfinger, he went up in rankings.
325
00:16:24,120 --> 00:16:25,880
Well, he needed to.
326
00:16:25,880 --> 00:16:27,120
Indeed he did.
327
00:16:27,120 --> 00:16:28,120
Okay.
328
00:16:28,120 --> 00:16:30,680
And then we'll put them in array, movies.
329
00:16:30,680 --> 00:16:36,599
We'll say movie one, movie two, and finally movie three, like that.
330
00:16:36,599 --> 00:16:39,079
So let's just see what happens if we try to sort them.
331
00:16:39,079 --> 00:16:40,079
Movies.sort.
332
00:16:40,079 --> 00:16:43,359
Because it's an array, we should be able to sort it.
333
00:16:43,359 --> 00:16:48,380
If we run that, we get this error, comparison of movie with movie failed.
334
00:16:48,380 --> 00:16:52,040
So Ruby doesn't know how to compare two movie objects.
335
00:16:52,040 --> 00:16:53,040
It knows about numbers.
336
00:16:53,040 --> 00:16:54,180
It knows about strings.
337
00:16:54,180 --> 00:16:55,800
But what about movie objects?
338
00:16:55,800 --> 00:16:57,959
Well, we could do something like this.
339
00:16:57,960 --> 00:17:00,760
We could use the sort by method and give it a block.
340
00:17:00,760 --> 00:17:02,080
It'll pass us each movie.
341
00:17:02,080 --> 00:17:04,480
And then we could do something like movie.rank.
342
00:17:04,480 --> 00:17:09,440
If we do that, then they get ranked lowest to highest.
343
00:17:09,440 --> 00:17:13,880
We kind of want our movies to be ranked high to low, right?
344
00:17:13,880 --> 00:17:16,440
So we could, I mean, we could pull a trick here.
345
00:17:16,440 --> 00:17:20,800
We could call the reverse method on that because that sort by method returns an array.
346
00:17:20,800 --> 00:17:22,360
We can reverse an array.
347
00:17:22,360 --> 00:17:24,120
And sure enough, that would work.
348
00:17:24,120 --> 00:17:26,240
But that doesn't feel like the right thing to do.
349
00:17:26,240 --> 00:17:30,480
What we really want to have happen is just to be able to call sort.
350
00:17:30,480 --> 00:17:35,160
Because anytime we sort movies, we really want them ranked high to low based on their
351
00:17:35,160 --> 00:17:36,160
ranking.
352
00:17:36,160 --> 00:17:40,640
So we want intrinsically to movies to be able to sort themselves that way.
353
00:17:40,640 --> 00:17:41,640
So how do we do that?
354
00:17:41,640 --> 00:17:47,040
Well, to answer that question, when we call sort on objects, Ruby uses something called
355
00:17:47,040 --> 00:17:51,760
the general comparison operator or sometimes called the spaceship operator to figure out
356
00:17:51,760 --> 00:17:53,000
how things should be sorted.
357
00:17:53,000 --> 00:17:54,440
Let me show you how that works.
358
00:17:54,440 --> 00:17:58,880
If we have movie one up here, the spaceship operator looks like this because kind of looks
359
00:17:58,880 --> 00:18:00,560
like a spaceship.
360
00:18:00,560 --> 00:18:03,240
And then you give it another object on the other side.
361
00:18:03,240 --> 00:18:07,680
So if we have like rank over here and we have movie.rank over there.
362
00:18:07,680 --> 00:18:09,800
So we're just going to compare those two things.
363
00:18:09,800 --> 00:18:12,480
I'm going to comment this out at the bottom just for a minute.
364
00:18:12,480 --> 00:18:15,540
Got to do a put us there so we see what happens.
365
00:18:15,540 --> 00:18:17,240
We get the value one.
366
00:18:17,240 --> 00:18:22,560
We get the value one because the rank of movie one is greater than the rank of movie two.
367
00:18:22,560 --> 00:18:25,620
So that's how it figures out, okay, this one's greater than another thing.
368
00:18:25,620 --> 00:18:31,040
If we were to have, for example, movie two over here and movie one over here.
369
00:18:31,040 --> 00:18:36,679
Well, then the general comparison operator returns negative one because movie two has
370
00:18:36,679 --> 00:18:38,520
a smaller rank than movie one.
371
00:18:38,520 --> 00:18:43,460
And if we were to compare movie one's rank with movie one's rank, it gets back zero.
372
00:18:43,460 --> 00:18:47,120
So the long and the short of that is this spaceship operator or the general comparison
373
00:18:47,120 --> 00:18:52,440
operator is used to figure out is the thing on the left hand side greater than equal to
374
00:18:52,440 --> 00:18:55,680
or less than the thing on the right hand side.
375
00:18:55,680 --> 00:19:00,160
And then based on that, the sort method can figure out how to sort things.
376
00:19:00,160 --> 00:19:02,240
Now we don't want to be writing this everywhere in our code.
377
00:19:02,240 --> 00:19:09,000
Instead, what we can do is we can leave movies.sort just as it is, go back over to our movie class
378
00:19:09,000 --> 00:19:13,860
and actually define or override that method as a method in the movie class.
379
00:19:13,860 --> 00:19:17,980
So we can create a method that is that general comparison operator.
380
00:19:17,980 --> 00:19:19,480
We can pass in another movie.
381
00:19:19,480 --> 00:19:21,880
I'm going to call this other movie.
382
00:19:21,880 --> 00:19:25,060
And then inside of here, we can say what we want to compare.
383
00:19:25,060 --> 00:19:30,480
We want to compare the other movie's rank to the current movie's rank, which is just
384
00:19:30,480 --> 00:19:33,040
in the rank instance variable.
385
00:19:33,040 --> 00:19:37,320
And if we do that, Ruby will automatically call this method when it needs to sort the
386
00:19:37,320 --> 00:19:38,320
movies.
387
00:19:38,320 --> 00:19:41,320
So we go back out to sorting.rb and we run it.
388
00:19:41,320 --> 00:19:44,480
Sure enough, we've got our movies ranked high to low.
389
00:19:44,480 --> 00:19:45,480
So let's put all this together.
390
00:19:45,480 --> 00:19:52,400
If we go back over to our playlist where we're printing out the movies in this play method,
391
00:19:52,400 --> 00:19:54,960
I can call put us at movies.sort.
392
00:19:54,960 --> 00:19:55,960
That's our array.
393
00:19:55,960 --> 00:19:59,840
So we could sort them when we're initially printing them out, as well down here in print
394
00:19:59,840 --> 00:20:04,700
stats when we're printing out the hits, we could call sort there and sort on flops because
395
00:20:04,700 --> 00:20:07,120
all of these are just movie arrays.
396
00:20:07,120 --> 00:20:10,540
Go back over to our main program file.
397
00:20:10,540 --> 00:20:11,960
We run it.
398
00:20:11,960 --> 00:20:14,200
They're sorted at the top based on their rankings.
399
00:20:14,200 --> 00:20:18,120
And if we look down at the bottom, we notice that Ghostbusters is hit.
400
00:20:18,120 --> 00:20:19,820
It's the only one in that list.
401
00:20:19,820 --> 00:20:22,400
And here we have Goonies has a rank of nine.
402
00:20:22,400 --> 00:20:25,320
It's above Goldfinger, which has a rank of zero.
403
00:20:25,320 --> 00:20:27,780
So we've got them sorted everywhere now.
404
00:20:27,780 --> 00:20:31,080
So in this section, we used a variety of blocks to do a variety of things.
405
00:20:31,080 --> 00:20:33,680
And in the exercise, you're going to do some similar things.
406
00:20:33,680 --> 00:20:35,760
You're going to iterate through a number of rounds.
407
00:20:35,760 --> 00:20:39,900
You're going to partition strong and wimpy players, and you're going to sort your players.
408
00:20:39,900 --> 00:20:42,620
Now we promised you earlier that we would revisit symbols.
409
00:20:42,620 --> 00:20:47,000
So we're going to do that next as well as learn about a new thing in Ruby, Strux.
410
00:20:47,000 --> 00:21:14,000
Sounds good.
36517
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.