All language subtitles for pragstudio-ruby-18-iterators (Transcribed on 27-Apr-2023 20-38-34)

af Afrikaans
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bn Bengali
bs Bosnian
bg Bulgarian
ca Catalan
ceb Cebuano
ny Chichewa
zh-CN Chinese (Simplified) Download
zh-TW Chinese (Traditional)
co Corsican
hr Croatian
cs Czech
da Danish
nl Dutch
en English
eo Esperanto
et Estonian
tl Filipino
fi Finnish
fr French
fy Frisian
gl Galician
ka Georgian
de German
el Greek
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
km Khmer
ko Korean
ku Kurdish (Kurmanji)
ky Kyrgyz
lo Lao
la Latin
lv Latvian
lt Lithuanian
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mn Mongolian
my Myanmar (Burmese)
ne Nepali
no Norwegian
ps Pashto
fa Persian
pl Polish
pt Portuguese
pa Punjabi
ro Romanian
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
st Sesotho
sn Shona
sd Sindhi
si Sinhala
sk Slovak
sl Slovenian
so Somali
es Spanish
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
te Telugu
th Thai
tr Turkish
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu
or Odia (Oriya)
rw Kinyarwanda
tk Turkmen
tt Tatar
ug Uyghur
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:08,620 So we've already seen some built-in iterators, like each, times, and up to, and folks sometimes 2 00:00:08,620 --> 00:00:11,200 think those are the only iterators you can use. 3 00:00:11,200 --> 00:00:14,180 But it turns out you can actually write your own iterator methods. 4 00:00:14,180 --> 00:00:17,660 So let's look at writing a couple basic iterators ourselves. 5 00:00:17,660 --> 00:00:21,700 So let's suppose we wanted to write an iterator method called once, and we want to pass it 6 00:00:21,700 --> 00:00:26,320 a block, or associate a block with that method call, and the block's just going to say, 7 00:00:26,320 --> 00:00:29,340 running your block, just like that. 8 00:00:29,340 --> 00:00:31,000 How would we implement this method? 9 00:00:31,000 --> 00:00:34,640 Well, to find the method, it's just a normal method. 10 00:00:34,640 --> 00:00:39,860 Inside of that method, to pass control over to the block, we call yield. 11 00:00:39,860 --> 00:00:45,200 So before we do that, I'm just going to print out before yield, and then after it, I'm going 12 00:00:45,200 --> 00:00:47,700 to print out after yield. 13 00:00:47,700 --> 00:00:51,280 And let's run it and see what happens. 14 00:00:51,280 --> 00:00:55,560 So it prints before yield, then it prints running your block, then it prints after yield. 15 00:00:55,560 --> 00:00:58,440 So what happened was we ran the method once. 16 00:00:58,440 --> 00:01:04,280 It ran its first statement here, before yield, then yield, pass control over to this block, 17 00:01:04,280 --> 00:01:06,140 and it printed running your block. 18 00:01:06,140 --> 00:01:08,280 Then the block exited, it was done. 19 00:01:08,280 --> 00:01:13,320 So then control passes back into the method, it finishes by printing after yield. 20 00:01:13,320 --> 00:01:14,720 Let's say we want a different iterator. 21 00:01:14,720 --> 00:01:16,840 Maybe we want the iterator to be called twice. 22 00:01:16,840 --> 00:01:18,280 We want to yield to the block twice. 23 00:01:18,280 --> 00:01:24,160 Well, we can just call yield multiple times inside of the method, change this over to 24 00:01:24,160 --> 00:01:25,160 twice. 25 00:01:25,160 --> 00:01:29,640 Now, if we run it, sure enough, we get before yield, it runs the block twice, and then we 26 00:01:29,640 --> 00:01:30,640 get after yield. 27 00:01:30,640 --> 00:01:35,200 How about we want the iterator to be called three times, but in this case, we want to 28 00:01:35,200 --> 00:01:37,060 do something slightly different. 29 00:01:37,060 --> 00:01:41,960 We want the iterator to pass the current iteration, like we've seen before with other iterator 30 00:01:41,960 --> 00:01:42,960 methods. 31 00:01:42,960 --> 00:01:46,580 So we want it to pass us the current number, and then inside of there, we're just going 32 00:01:46,580 --> 00:01:49,460 to print out the number that it gives us. 33 00:01:49,460 --> 00:01:51,179 Number like that. 34 00:01:51,180 --> 00:01:58,080 So the method's going to be called three times, and then instead of before yield, I'm just 35 00:01:58,080 --> 00:01:59,080 going to print here. 36 00:01:59,080 --> 00:02:01,040 I'm going to say ready. 37 00:02:01,040 --> 00:02:02,160 We're going to yield. 38 00:02:02,160 --> 00:02:07,140 Now, any parameters that we pass to yield are going to get passed off to the associated 39 00:02:07,140 --> 00:02:08,140 block. 40 00:02:08,140 --> 00:02:10,720 So we could call yield and pass in the number one, right? 41 00:02:10,720 --> 00:02:15,200 And then I'm going to print, put as set, and then we could call yield again. 42 00:02:15,200 --> 00:02:16,560 Yield is a method here. 43 00:02:16,560 --> 00:02:22,320 I can use the actual parentheses for two, or I could just say yield two because parentheses 44 00:02:22,320 --> 00:02:23,320 in Ruby are optional. 45 00:02:23,320 --> 00:02:29,320 So then I can say yield two, this would be go, and then I could say yield three, just 46 00:02:29,320 --> 00:02:30,320 like that. 47 00:02:30,320 --> 00:02:34,560 So now if we run that, we see it yielded to our block three times, and it gave it the 48 00:02:34,560 --> 00:02:37,120 numbers one, two, and three. 49 00:02:37,120 --> 00:02:38,720 Now that's pretty cool. 50 00:02:38,720 --> 00:02:40,840 Let's look at that in slow motion. 51 00:02:40,840 --> 00:02:44,360 We call the three times method with an associated block. 52 00:02:44,360 --> 00:02:48,840 The method begins to execute, the first thing it does is print ready. 53 00:02:48,840 --> 00:02:52,340 Then the method calls yield, passing the number one. 54 00:02:52,340 --> 00:02:55,560 At that point, the associated block is invoked. 55 00:02:55,560 --> 00:03:01,100 The value we pass to yield, the number one, is assigned to the block parameter number. 56 00:03:01,100 --> 00:03:02,940 The block prints one. 57 00:03:02,940 --> 00:03:06,040 Then the block returns control back over to the method. 58 00:03:06,040 --> 00:03:07,960 The method prints set. 59 00:03:07,960 --> 00:03:12,520 Then it yields to the block again, passing in two, and the block prints two. 60 00:03:12,520 --> 00:03:18,080 Then we go back to the method, it prints go, and then we yield to the block a third time, 61 00:03:18,080 --> 00:03:21,560 passing three, and the block prints three. 62 00:03:21,560 --> 00:03:24,740 And then we come back to the method, and it ends. 63 00:03:24,740 --> 00:03:29,120 So the cool thing about these iterator methods is they decouple the actual looping from what 64 00:03:29,120 --> 00:03:30,560 happens during each iteration. 65 00:03:30,560 --> 00:03:32,160 Here, let me show you. 66 00:03:32,160 --> 00:03:33,920 So we could change this inside of here. 67 00:03:33,920 --> 00:03:38,360 Instead of just printing out the number, we could say maybe it's the number times two, 68 00:03:38,360 --> 00:03:39,360 for example. 69 00:03:39,360 --> 00:03:43,720 If we run this code, the iterator does exactly the same thing, but when it turns control 70 00:03:43,720 --> 00:03:47,560 over to our block, now we're multiplying the number by two. 71 00:03:47,560 --> 00:03:52,360 Or maybe we want to just take number times number, one, four, and nine. 72 00:03:52,360 --> 00:03:54,400 So our iterator method stays the same. 73 00:03:54,400 --> 00:03:58,660 We don't have to change it at all, but we can change what happens during each iteration 74 00:03:58,660 --> 00:04:01,880 simply by changing what's inside of the block. 75 00:04:01,880 --> 00:04:04,040 Now blocks can also return a value. 76 00:04:04,040 --> 00:04:08,920 So the last expression that's evaluated by the block will be returned as the value of 77 00:04:08,920 --> 00:04:09,920 the yield. 78 00:04:09,920 --> 00:04:10,920 Let's look at that. 79 00:04:10,920 --> 00:04:12,119 I'm just going to clean this code up. 80 00:04:12,119 --> 00:04:13,559 I don't want to do that. 81 00:04:13,559 --> 00:04:14,839 And I'm going to write a new iterator. 82 00:04:14,839 --> 00:04:17,700 Let's call it compute. 83 00:04:17,700 --> 00:04:22,960 Inside of that method, I'm going to yield, but then I want to print out the result of 84 00:04:22,960 --> 00:04:24,560 calling yield. 85 00:04:24,560 --> 00:04:25,560 So let's see what happens. 86 00:04:25,560 --> 00:04:30,120 If we call compute, we're going to pass it a block, and I'm just going to return. 87 00:04:30,120 --> 00:04:32,200 The block's just going to say hello like that. 88 00:04:32,200 --> 00:04:36,000 So if I run it now, then I see that it prints hello. 89 00:04:36,000 --> 00:04:41,680 Even though I'm not using a put s here, this string is getting returned by the block here, 90 00:04:41,680 --> 00:04:44,620 and then the put s is then printing that string to the console. 91 00:04:44,620 --> 00:04:46,240 So let's say we had multiple statements in here. 92 00:04:46,240 --> 00:04:49,740 Maybe we had like 7, 3.14. 93 00:04:49,740 --> 00:04:54,560 If I run this now, well, the result of that block is 3.14, and it gets printed because 94 00:04:54,560 --> 00:04:58,500 it's the last expression that's evaluated inside of the block. 95 00:04:58,500 --> 00:05:02,000 But what happens if we try to call the iterator method without a block? 96 00:05:02,000 --> 00:05:07,480 Well, if we just take the block off of here and we call it, we get this method local jump 97 00:05:07,480 --> 00:05:08,480 error. 98 00:05:08,480 --> 00:05:09,480 Wow, that looks scary. 99 00:05:09,480 --> 00:05:11,680 No block given to yield. 100 00:05:11,680 --> 00:05:16,200 So if we've got a yield just like this, it expects there to be an associated block, and 101 00:05:16,200 --> 00:05:17,540 it tries to call it. 102 00:05:17,540 --> 00:05:21,840 But we can get around that a little bit by using a conditional. 103 00:05:21,840 --> 00:05:26,140 We can say if block underscore given, that's a built-in Ruby method. 104 00:05:26,140 --> 00:05:29,120 If a block is given, then go ahead and yield to it. 105 00:05:29,120 --> 00:05:35,640 Else, we'll just print out something like does not compute. 106 00:05:35,640 --> 00:05:38,720 So now if I run it, no blocks given, we get does not compute. 107 00:05:38,720 --> 00:05:41,120 Otherwise, I can put a block in here. 108 00:05:41,120 --> 00:05:46,840 Maybe the block just says the number 3.14, for example, and then the block runs. 109 00:05:46,840 --> 00:05:50,640 So what happens when we combine iterator methods with blocks that return values? 110 00:05:50,640 --> 00:05:52,840 Well, here's something kind of clever about Ruby. 111 00:05:52,840 --> 00:05:57,120 I'm just going to clean up this file here, and let's start with something else. 112 00:05:57,120 --> 00:06:00,400 Remember, let's just create an array. 113 00:06:00,400 --> 00:06:04,400 Let's say it's 10 numbers, right? 114 00:06:04,400 --> 00:06:07,080 And remember our old friend select. 115 00:06:07,080 --> 00:06:12,880 We could call select on that array, and it gives us a value, and then we select out all 116 00:06:12,880 --> 00:06:14,920 the ones that are even, for example. 117 00:06:14,920 --> 00:06:19,240 So if we run that, we get all the even numbers. 118 00:06:19,240 --> 00:06:24,200 And that select looks kind of special, but let's think about how we might actually implement 119 00:06:24,200 --> 00:06:27,400 that in Ruby. 120 00:06:27,400 --> 00:06:32,640 Let's define a method called mySelect, just to keep it separate from the select that's 121 00:06:32,640 --> 00:06:34,120 built into array. 122 00:06:34,120 --> 00:06:37,620 And it would take, let's say, an array as a parameter there. 123 00:06:37,620 --> 00:06:39,560 So we're not going to put this on the array class. 124 00:06:39,560 --> 00:06:42,840 We're just going to have our own method, mySelect, that takes an array. 125 00:06:42,840 --> 00:06:44,400 How would we implement select? 126 00:06:44,400 --> 00:06:49,360 Well, clearly, we want to be able to create an array and return it that just has the elements 127 00:06:49,360 --> 00:06:50,360 that we've selected. 128 00:06:50,360 --> 00:06:55,040 So let's just start with saying that the results is an empty array, and at the end, we want 129 00:06:55,040 --> 00:06:57,840 to be able to return those results. 130 00:06:57,840 --> 00:07:02,120 Then what we want to do is just loop through each of the elements in the array using a 131 00:07:02,120 --> 00:07:03,700 built-in iterator. 132 00:07:03,700 --> 00:07:06,760 It's going to give us each element in that array. 133 00:07:06,760 --> 00:07:12,320 And now what we want to do is capture all the elements of that array that match some 134 00:07:12,320 --> 00:07:13,540 criteria. 135 00:07:13,540 --> 00:07:20,820 So we want to append to our results array that element that we're looping through, only 136 00:07:20,820 --> 00:07:26,000 if the result of running some block says that we should include that element. 137 00:07:26,000 --> 00:07:30,520 So what we can do is we can say, OK, go ahead and run the block, yield, and give the block 138 00:07:30,520 --> 00:07:34,840 the element so it can decide whether it should include it or not. 139 00:07:34,840 --> 00:07:36,760 Then we can just call our method. 140 00:07:36,760 --> 00:07:39,560 We'll just use putS, mySelect. 141 00:07:39,560 --> 00:07:41,240 We'll pass in our numbers array. 142 00:07:41,240 --> 00:07:42,680 It's going to yield to a block. 143 00:07:42,680 --> 00:07:44,640 So let's give it a block just like that. 144 00:07:44,640 --> 00:07:47,320 It's also going to give us the element, in this case n. 145 00:07:47,320 --> 00:07:50,280 The block looks just like it does with a regular select. 146 00:07:50,280 --> 00:07:57,160 If I just take off the select up here, and we run this now, we get all the even numbers. 147 00:07:57,160 --> 00:08:01,560 So that gives us some insight into how select, reject, partition, and some of these other 148 00:08:01,560 --> 00:08:05,100 iterator methods we've used actually work. 149 00:08:05,100 --> 00:08:09,080 So this is all kind of interesting, but what's a practical use of an iterator like this? 150 00:08:09,080 --> 00:08:15,560 Well, I have an idea where this could be useful.In the game, you're currently printing this. 151 00:08:15,560 --> 00:08:21,140 And it would be nice to be able to print each player's points on a per-treasure basis. 152 00:08:21,140 --> 00:08:25,960 And in the same way, our playlist is currently printing something like this. 153 00:08:25,960 --> 00:08:31,400 And we want to be able to print each movie's snacks on a per-snack basis. 154 00:08:31,400 --> 00:08:33,539 So let's recap where things stand. 155 00:08:33,539 --> 00:08:38,199 When a movie is played, a random snack is snagged from the snack bar. 156 00:08:38,200 --> 00:08:43,680 In the movie object, we call 8 snack and then pass in the random snack object. 157 00:08:43,680 --> 00:08:48,720 The movie then stores the snack's name and accumulated carbs in a hash. 158 00:08:48,720 --> 00:08:54,600 So in this example, two popcorns were consumed for a total of 40 carbs, and one soda, or 159 00:08:54,600 --> 00:08:58,160 pop, was consumed for 5 carbs. 160 00:08:58,160 --> 00:09:03,880 We can then print out the grand total number of carbs consumed, 45 in this case. 161 00:09:03,880 --> 00:09:07,880 Now we want to be able to print out each movie's snacks on a per-snack basis. 162 00:09:07,880 --> 00:09:10,780 We don't want to expose the hash outside of the movie. 163 00:09:10,780 --> 00:09:13,520 How it stores snacks is an implementation detail. 164 00:09:13,520 --> 00:09:19,280 Instead, we'll write an each snack iterator method that hands out snack objects representing 165 00:09:19,280 --> 00:09:21,160 what's in the hash. 166 00:09:21,160 --> 00:09:23,700 Here's how we'll use that iterator method. 167 00:09:23,700 --> 00:09:28,360 Each snack yields snack objects to an associated block. 168 00:09:28,360 --> 00:09:33,500 So the first time through, the block will print 40 total popcorn carbs. 169 00:09:33,500 --> 00:09:38,280 And then the second time through, it'll print 5 total soda carbs. 170 00:09:38,280 --> 00:09:42,800 Yeah, and if we put this code in the printStats method of the playlist class, then we get 171 00:09:42,800 --> 00:09:44,440 the output we're aiming for. 172 00:09:44,440 --> 00:09:48,140 And the playlist class, which you can think of as a client to the movie class, will be 173 00:09:48,140 --> 00:09:51,500 none the wiser about how snacks are stored in the movie. 174 00:09:51,500 --> 00:09:53,240 So let's do that. 175 00:09:53,240 --> 00:09:56,940 So we're over in our playlist class in this printStats method, and what we want to do 176 00:09:56,940 --> 00:10:00,760 is right now we're just printing out the movie's grand total carbs. 177 00:10:00,760 --> 00:10:05,200 And what we want to be able to do, the code we want to be able to write here is to take 178 00:10:05,200 --> 00:10:09,060 the movie, this is the movie inside of this loop, and we want to be able to call an iterator 179 00:10:09,060 --> 00:10:11,800 like each snack. 180 00:10:11,800 --> 00:10:15,840 And then that iterator method should give us a snack object like that. 181 00:10:15,840 --> 00:10:25,700 And then inside of the block, we want to be able to print out snack carbs total snack 182 00:10:25,700 --> 00:10:28,000 name carbs. 183 00:10:28,000 --> 00:10:32,480 Should be something like 15 total soda carbs, for example. 184 00:10:32,480 --> 00:10:35,920 So the movie is going to vend out these snacks to us using this iterator method. 185 00:10:35,920 --> 00:10:36,920 So let's go write that. 186 00:10:36,920 --> 00:10:40,840 Go over to movie, and write our iterator. 187 00:10:40,840 --> 00:10:44,880 It's going to be called each snack. 188 00:10:44,880 --> 00:10:45,880 What's it going to do? 189 00:10:45,880 --> 00:10:48,960 Well, we're going to take our snack carbs hash. 190 00:10:48,960 --> 00:10:52,080 We're going to iterate through the keys and the values for it. 191 00:10:52,080 --> 00:10:54,280 Let me set up my block here. 192 00:10:54,280 --> 00:10:55,600 This is going to be the name. 193 00:10:55,600 --> 00:10:57,440 This is going to be the carbs. 194 00:10:57,440 --> 00:11:02,960 So remember, when we gave the snack object to the movie via the eight snack method, we 195 00:11:02,960 --> 00:11:06,120 deconstructed it into name and carbs inside of our hash. 196 00:11:06,120 --> 00:11:08,080 Now we want to put that back together again. 197 00:11:08,080 --> 00:11:11,200 So we want to be able to yield an actual snack object. 198 00:11:11,200 --> 00:11:13,200 So let's create a snack object. 199 00:11:13,200 --> 00:11:15,200 Snack.new. 200 00:11:15,200 --> 00:11:23,140 The name of the snack is the key of our hash, and the carbs of the snack is the value of 201 00:11:23,140 --> 00:11:26,560 our hash, which came in in this second parameter here. 202 00:11:26,560 --> 00:11:29,959 So we're just taking the key value pair out of the hash, and we're constructing a new 203 00:11:29,959 --> 00:11:31,819 snack object. 204 00:11:31,819 --> 00:11:36,839 Then we'll just yield that snack object over to the block. 205 00:11:36,839 --> 00:11:37,839 We save that. 206 00:11:37,839 --> 00:11:41,680 If we look back in our playlist method, we're expecting a snack object here, because we're 207 00:11:41,680 --> 00:11:45,160 going to look at its carbs and its snack and its snack name. 208 00:11:45,160 --> 00:11:48,540 So now we should be able to go over to flix.rb. 209 00:11:48,540 --> 00:11:54,319 And if we run it and look at the bottom, now we've got our total carbs at the top. 210 00:11:54,320 --> 00:12:00,840 And then for each movie, we've got a breakdown of the carbs for each particular snack, and 211 00:12:00,840 --> 00:12:02,800 then the total at the bottom. 212 00:12:02,800 --> 00:12:05,720 Now you're probably not going to write your own iterator method all that often, but in 213 00:12:05,720 --> 00:12:08,320 certain situations, they come in really handy. 214 00:12:08,320 --> 00:12:11,280 In this case, we made the movie class easier to use. 215 00:12:11,280 --> 00:12:15,320 In the same way we can ask an array for all of its elements, we can ask a movie for all 216 00:12:15,320 --> 00:12:16,800 of its snacks. 217 00:12:16,800 --> 00:12:19,800 And in the exercise, you're going to do something very similar. 218 00:12:19,800 --> 00:12:24,439 You're going to print out each player's points on a per-treasure basis. 219 00:12:24,439 --> 00:12:28,040 Then when you come back, we'll look at taking some user input from the command line or the 220 00:12:28,040 --> 00:12:31,520 console, and we'll also look at how to read and write to files. 221 00:12:31,520 --> 00:12:34,319 We'll see you then. 222 00:12:34,319 --> 00:12:37,359 You'll kind of be like... 223 00:12:37,359 --> 00:12:38,920 I don't know how to fake laugh. 224 00:12:38,920 --> 00:12:39,920 That's the problem. 225 00:12:39,920 --> 00:12:40,920 It's hard. 226 00:12:40,920 --> 00:12:41,920 It is really... 227 00:12:41,920 --> 00:12:42,920 It would come out so cheesy. 228 00:12:42,920 --> 00:12:43,920 I'd be like, haha! 229 00:12:43,920 --> 00:12:44,920 Okay. 230 00:12:44,920 --> 00:12:45,920 I could do that. 231 00:12:45,920 --> 00:12:46,920 Well, I'll laugh at my own joke. 232 00:12:46,920 --> 00:12:47,920 Should I do that, Matt? 233 00:12:47,920 --> 00:12:49,920 No. 20804

Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.