All language subtitles for pragstudio-ruby-blocks-09-manage-resources (Transcribed on 27-Apr-2023 21-03-09)

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:07,480 So blocks come in really handy when you need to control and resource. 2 00:00:07,480 --> 00:00:10,360 Maybe it's a network connection, maybe it's a file. 3 00:00:10,360 --> 00:00:15,900 Yeah, you need to connect and disconnect and open and close the resource and guarantee that 4 00:00:15,900 --> 00:00:18,800 everything is cleaned up properly at the end. 5 00:00:18,800 --> 00:00:23,640 For example, let's suppose we have a simple payment gateway class and imagine it talks 6 00:00:23,640 --> 00:00:25,680 to a remote web service. 7 00:00:25,680 --> 00:00:30,200 It needs to be initialized with a super secret username and password. 8 00:00:30,200 --> 00:00:35,080 We have a way to connect and disconnect from the remote service. 9 00:00:35,080 --> 00:00:40,760 We also have a way to submit transactions by specifying the type of transaction, maybe 10 00:00:40,760 --> 00:00:44,920 a sale or a refund and also send the amount. 11 00:00:44,920 --> 00:00:47,120 So here's the way we typically use it. 12 00:00:47,120 --> 00:00:49,600 We create a new gateway object. 13 00:00:49,600 --> 00:00:51,519 We connect to it. 14 00:00:51,520 --> 00:00:57,120 We send some transactions and then we have to remember to disconnect when we're done. 15 00:00:57,120 --> 00:00:58,520 So let's see that that works. 16 00:00:58,520 --> 00:00:59,920 All right, we run it. 17 00:00:59,920 --> 00:01:01,280 We connect it as Nicole. 18 00:01:01,280 --> 00:01:06,040 We submitted two sales and transactions and then we disconnect the due. 19 00:01:06,040 --> 00:01:09,760 Now code like this tends to sprout up in other areas of our app. 20 00:01:09,760 --> 00:01:13,960 For example, imagine somewhere else we handle refunds. 21 00:01:13,960 --> 00:01:17,120 So we basically have to do the same thing. 22 00:01:17,120 --> 00:01:19,040 So let's see that that works. 23 00:01:19,040 --> 00:01:23,560 Yep, we submitted your sale transactions and then we turned around, reconnected you, 24 00:01:23,560 --> 00:01:27,200 sent to refunds and disconnected at the end. 25 00:01:27,200 --> 00:01:29,120 Now obviously this is an ideal. 26 00:01:29,120 --> 00:01:33,720 We have the need to connect and disconnect around a whole series of transactions. 27 00:01:33,720 --> 00:01:38,920 Yeah, instead we could use a block and get some automatic resource management. 28 00:01:38,920 --> 00:01:43,840 So we're going to define a method that takes a block and then execute around the transactions 29 00:01:43,840 --> 00:01:44,840 in the block. 30 00:01:44,840 --> 00:01:46,800 So I'm going to define the method right up here. 31 00:01:46,800 --> 00:01:50,200 It's going to be called, let's start with a method outside the class. 32 00:01:50,200 --> 00:01:52,600 We're going to call it open gateway. 33 00:01:52,600 --> 00:01:55,000 It's going to need to take the user in the password. 34 00:01:55,000 --> 00:01:57,160 All right, what are we doing inside that method? 35 00:01:57,160 --> 00:02:02,000 Well, the very first thing we need to do is actually create a new payment gateway. 36 00:02:02,000 --> 00:02:07,360 And instead of using these hard-coded values, we'll use user and password here. 37 00:02:07,360 --> 00:02:09,759 So we'll just forward those onto the gateway. 38 00:02:09,759 --> 00:02:13,360 Then we need to do gateway connect. 39 00:02:13,360 --> 00:02:15,000 Then we want to yield to the block. 40 00:02:15,000 --> 00:02:16,000 Let it do the transactions. 41 00:02:16,000 --> 00:02:21,920 And then when we're done, we need to make sure that we actually disconnect from the gateway. 42 00:02:21,920 --> 00:02:26,400 Now the block itself is going to need the gateway object so we can run the transactions. 43 00:02:26,400 --> 00:02:31,840 So when we call yield, we're going to have to pass in that gateway object. 44 00:02:31,840 --> 00:02:34,200 Now down here, we're submitting the transactions. 45 00:02:34,200 --> 00:02:37,080 We'll call our open gateway method. 46 00:02:37,080 --> 00:02:38,080 We just wrote here. 47 00:02:38,080 --> 00:02:43,200 This will be Nicole and Secret. 48 00:02:43,200 --> 00:02:46,600 The block parameter is the gateway itself. 49 00:02:46,600 --> 00:02:50,079 Inside the block, we can then use that gateway object. 50 00:02:50,079 --> 00:02:55,519 And we don't have to worry about disconnecting it because when the block ends, the yield is returned. 51 00:02:55,519 --> 00:02:57,519 Remember, we're just going to disconnect right there. 52 00:02:57,519 --> 00:03:01,120 So we've got all this encapsulated in one nice little method. 53 00:03:01,120 --> 00:03:02,959 So we save this and run it. 54 00:03:02,959 --> 00:03:04,280 What we get the same output before. 55 00:03:04,280 --> 00:03:06,320 We saw we connected as Nicole. 56 00:03:06,320 --> 00:03:07,760 Then we submitted a sale transaction. 57 00:03:07,760 --> 00:03:09,959 Actually, two sale transactions. 58 00:03:09,960 --> 00:03:13,400 And the block disconnected us at the very end. 59 00:03:13,400 --> 00:03:18,760 So we've got some automatic resource management going on inside of this method, executing 60 00:03:18,760 --> 00:03:21,280 around this block. 61 00:03:21,280 --> 00:03:24,800 So now that we've got it working, let's make a little design improvement here. 62 00:03:24,800 --> 00:03:28,480 Well let's say we want to move this method inside of our payment gateway class. 63 00:03:28,480 --> 00:03:32,280 We're just going to move, we're inside of the class right here. 64 00:03:32,280 --> 00:03:33,480 Right? 65 00:03:33,480 --> 00:03:35,440 And right now it's an instance method. 66 00:03:35,440 --> 00:03:39,840 We would have to have a payment gateway object in order to call this method. 67 00:03:39,840 --> 00:03:42,960 We're not going to have a payment gateway object because we don't create one until the 68 00:03:42,960 --> 00:03:44,280 method is actually run. 69 00:03:44,280 --> 00:03:48,400 So we're going to change this to be a class method by using self dot. 70 00:03:48,400 --> 00:03:50,960 And then we're going to change the name of the method because it's pretty clear if 71 00:03:50,960 --> 00:03:54,720 it's a class method on the payment gateway that we don't need to call it open gateway. 72 00:03:54,720 --> 00:03:58,040 We would just call it open because we know what we're opening there. 73 00:03:58,040 --> 00:04:01,520 One small refinement here is if you're inside of a class method and you want to get 74 00:04:01,520 --> 00:04:06,760 to hold the class, weld the self variable points to the payment gateway class here. 75 00:04:06,760 --> 00:04:11,079 So we can change payment gateway class to just self right there. 76 00:04:11,079 --> 00:04:17,560 Now to call that method down here instead of using open gateway, we call payment gateway. 77 00:04:17,560 --> 00:04:18,880 That's the name of the class. 78 00:04:18,880 --> 00:04:20,719 It defines a method called open. 79 00:04:20,719 --> 00:04:22,599 It's a class level method. 80 00:04:22,599 --> 00:04:23,599 Just like that. 81 00:04:23,599 --> 00:04:24,599 And that should run as well. 82 00:04:24,599 --> 00:04:27,880 I'm going to go ahead and change this one for doing refunds. 83 00:04:27,880 --> 00:04:29,760 So we look like this. 84 00:04:29,760 --> 00:04:32,719 Payment gateway. 85 00:04:32,720 --> 00:04:38,120 We need to take the block parameter which is a gateway like that. 86 00:04:38,120 --> 00:04:39,120 We don't need to connect. 87 00:04:39,120 --> 00:04:41,040 That's already handled in the open method. 88 00:04:41,040 --> 00:04:44,240 We're going to submit our transactions and we don't need to disconnect because that's 89 00:04:44,240 --> 00:04:46,240 automatically handled for us. 90 00:04:46,240 --> 00:04:47,240 Save those off. 91 00:04:47,240 --> 00:04:49,680 And we get the same result we got before. 92 00:04:49,680 --> 00:04:53,240 We submit our self transactions and our refund transactions. 93 00:04:53,240 --> 00:04:58,200 But the really nice thing is this code is a lot more compact and expressive. 94 00:04:58,200 --> 00:05:02,200 We don't have to worry about connecting and disconnecting in the right order. 95 00:05:02,200 --> 00:05:06,000 The method called open handles all that for us. 96 00:05:06,000 --> 00:05:11,880 So what if we want to create a connected gateway but not using associated block? 97 00:05:11,880 --> 00:05:14,200 Like let's say we want to do a special scenario. 98 00:05:14,200 --> 00:05:16,640 We want to void a transaction. 99 00:05:16,640 --> 00:05:19,200 We would still need to open the gateway. 100 00:05:19,200 --> 00:05:21,520 Okay, well let's take this open method here. 101 00:05:21,520 --> 00:05:25,159 I'm just going to copy that so it's a bit easier. 102 00:05:25,159 --> 00:05:27,440 And we'd like to just assign it to a variable. 103 00:05:27,440 --> 00:05:30,640 We'd have the open method return to us a gateway object. 104 00:05:30,640 --> 00:05:32,719 But then we're going to manage it from here. 105 00:05:32,719 --> 00:05:36,039 So we would then use gateway and we would submit. 106 00:05:36,039 --> 00:05:39,960 You said it was a void transaction, maybe for $15. 107 00:05:39,960 --> 00:05:44,039 And then because we don't have a block here, we're going to go ahead and disconnect it. 108 00:05:44,039 --> 00:05:48,719 So we're responsible for disconnecting it because we're not passing an associated block 109 00:05:48,719 --> 00:05:49,960 to that open method. 110 00:05:49,960 --> 00:05:50,960 But that's okay. 111 00:05:50,960 --> 00:05:53,960 We want to take some more fine grain control when we do this. 112 00:05:53,960 --> 00:05:58,120 So if we try to run this, well we get this local jump error. 113 00:05:58,120 --> 00:06:02,840 We saw a little bit earlier in the course because we haven't associated a block and we're 114 00:06:02,840 --> 00:06:05,840 calling yield up here, we get this error. 115 00:06:05,840 --> 00:06:06,840 Now it's up to you. 116 00:06:06,840 --> 00:06:11,520 It's a design decision whether you want to require a block or you want somebody to be 117 00:06:11,520 --> 00:06:13,640 able to pass a block or not pass a block. 118 00:06:13,640 --> 00:06:15,960 In our case, we want to support both scenarios. 119 00:06:15,960 --> 00:06:16,960 All right. 120 00:06:16,960 --> 00:06:22,200 And you might think the way to handle this would be to call if block is given just as we 121 00:06:22,200 --> 00:06:24,760 have done before in other scenarios. 122 00:06:24,760 --> 00:06:29,039 But that's not going to work in this scenario because let's look at what happens. 123 00:06:29,039 --> 00:06:33,760 When we call the open method right here without a block, so it's going to create a new 124 00:06:33,760 --> 00:06:36,880 gateway object, it's then going to connect to it. 125 00:06:36,880 --> 00:06:40,520 It's then going to get the this line is going to say, well, a block wasn't given, so 126 00:06:40,520 --> 00:06:42,280 I'm not going to yield to the block. 127 00:06:42,280 --> 00:06:44,960 But it is going to try to disconnect the block. 128 00:06:44,960 --> 00:06:49,920 So what's going to happen here is we're not going to get an object back because no object 129 00:06:49,920 --> 00:06:51,640 was ever passed back to us. 130 00:06:51,640 --> 00:06:55,919 The method tries to do everything for us inside of that method. 131 00:06:55,919 --> 00:06:57,360 So what do we want to do instead? 132 00:06:57,360 --> 00:07:02,000 Well, we need to get back a gateway object that's connected has been disconnected and we can 133 00:07:02,000 --> 00:07:03,520 do whatever we want with it. 134 00:07:03,520 --> 00:07:05,039 So here's a little trick. 135 00:07:05,039 --> 00:07:10,400 Right here after we've connected, we're going to return that gateway object. 136 00:07:10,400 --> 00:07:13,520 We're only going to return the object if a block hasn't been given. 137 00:07:13,520 --> 00:07:17,080 So unless block is given, return the object. 138 00:07:17,080 --> 00:07:22,359 Otherwise, go ahead and yield to it. We don't need the if block given right there. 139 00:07:22,359 --> 00:07:26,440 So if a block isn't supplied, just go ahead and return the gateway and these lines of code 140 00:07:26,440 --> 00:07:27,599 won't be run. 141 00:07:27,599 --> 00:07:31,200 If a block is supplied, do the normal thing, yield to it and disconnect when you're 142 00:07:31,200 --> 00:07:32,200 all done. 143 00:07:32,200 --> 00:07:35,440 So if we save this, now we can use it in multiple scenarios. 144 00:07:35,440 --> 00:07:40,039 We see that we can submit our void transaction, our sales, and our refunds. 145 00:07:40,039 --> 00:07:43,560 We can call the open method with or without a block. 146 00:07:43,560 --> 00:07:47,000 So using block given gives the method two different behaviors. 147 00:07:47,000 --> 00:07:50,640 When it's called with a block, it executes the block and disconnects. 148 00:07:50,640 --> 00:07:54,960 When it's called without a block, it simply returns the gateway object. 149 00:07:54,960 --> 00:08:00,120 Again, it's a design decision whether you want to allow your methods to take blocks or 150 00:08:00,120 --> 00:08:02,480 optionally not take blocks. 151 00:08:02,480 --> 00:08:09,400 But wait, what happens if our block encounters an exception while it's issuing refunds? 152 00:08:09,400 --> 00:08:11,040 Well, we know how to handle that. 153 00:08:11,040 --> 00:08:12,640 We do. 154 00:08:12,640 --> 00:08:16,000 So let's simulate a problem here inside of this refund block. 155 00:08:16,000 --> 00:08:17,680 We're going to raise an exception. 156 00:08:17,680 --> 00:08:20,960 This time, I'm just going to say, oh, problem, exclamation point. 157 00:08:20,960 --> 00:08:21,960 Right? 158 00:08:21,960 --> 00:08:24,520 If we run that, well, our exception is not handled. 159 00:08:24,520 --> 00:08:26,039 We don't want to rescue you clause or anything. 160 00:08:26,039 --> 00:08:28,000 So it propagates all the way up to the top. 161 00:08:28,000 --> 00:08:31,080 But let's look at what happened in the printouts here. 162 00:08:31,080 --> 00:08:37,559 We submitted a refund for $5 and $20, but notice after the refund, our connection wasn't 163 00:08:37,559 --> 00:08:38,559 disconnected. 164 00:08:38,559 --> 00:08:41,319 We don't see a disconnect after this line right here. 165 00:08:41,320 --> 00:08:44,640 Now, and that's because we raised an exception inside of the block. 166 00:08:44,640 --> 00:08:49,720 If we go look inside of our open method, it's not handling exceptions at all. 167 00:08:49,720 --> 00:08:54,640 So when we yield to the block, the exception is going to stop the program from executing 168 00:08:54,640 --> 00:08:55,880 right at this point. 169 00:08:55,880 --> 00:08:59,600 So we're never going to get to this line of code which disconnects the gateway. 170 00:08:59,600 --> 00:09:04,560 So we need to guarantee or ensure that the gateway is disconnected even if the block raises 171 00:09:04,560 --> 00:09:05,560 an exception. 172 00:09:05,560 --> 00:09:09,320 And we know how to do that using our old friend the insure clause. 173 00:09:09,320 --> 00:09:14,480 So we're just going to take that chunk of code and put it inside of it and sure like that. 174 00:09:14,480 --> 00:09:20,360 So if an exception is raised here, we know that that line of code will always be executed. 175 00:09:20,360 --> 00:09:25,920 If we run it now, notice we get the line after the refunds disconnected in a call. 176 00:09:25,920 --> 00:09:28,360 So the disconnect happened. 177 00:09:28,360 --> 00:09:30,200 But there's a small problem here. 178 00:09:30,200 --> 00:09:33,960 Imagine up in this code where we're creating a new gateway with new. 179 00:09:33,960 --> 00:09:37,560 Imagine somewhere in that code, it raised an exception. 180 00:09:37,560 --> 00:09:41,839 Well if it raises an exception up here in this line of code, ensure we'll still be called, 181 00:09:41,839 --> 00:09:44,400 it will try to disconnect the gateway. 182 00:09:44,400 --> 00:09:48,400 But if it raises an exception up here, then it will never be connected in the first place 183 00:09:48,400 --> 00:09:53,439 and we'll try to disconnect a gateway that hasn't been connected in the first place. 184 00:09:53,439 --> 00:09:58,520 So we need to be a little bit more selective about which lines of code the insure clause 185 00:09:58,520 --> 00:10:00,000 applies to. 186 00:10:00,000 --> 00:10:02,280 And we can do that using begin. 187 00:10:02,280 --> 00:10:05,959 We only want to ensure to be applied to this line of code when we're yielding to the 188 00:10:05,959 --> 00:10:06,959 block. 189 00:10:06,960 --> 00:10:10,320 So we can say begin. 190 00:10:10,320 --> 00:10:11,560 All right. 191 00:10:11,560 --> 00:10:17,960 That's yielding to the block and we want to ensure that that happens after that block is run. 192 00:10:17,960 --> 00:10:23,920 So we've got a begin, some statement, and then ensure only gets applied to that section 193 00:10:23,920 --> 00:10:24,920 of code. 194 00:10:24,920 --> 00:10:30,320 And we know by this point our gateway is already connected so we're good to go. 195 00:10:30,320 --> 00:10:32,360 Now as things stand, there's no rescue clause. 196 00:10:32,360 --> 00:10:36,040 So any exception is still going to get propagated all the way to the top. 197 00:10:36,040 --> 00:10:42,640 And we could optionally add a rescue clause here as we did before rescue exception, 198 00:10:42,640 --> 00:10:45,800 e, and we could print out the message associated with that. 199 00:10:45,800 --> 00:10:50,439 And again, this rescue clause only applies to that line of code. 200 00:10:50,439 --> 00:10:55,640 So the takeaway here is we've got resource management and exception handling encapsulated 201 00:10:55,640 --> 00:10:59,000 in this one spot in this one open method. 202 00:10:59,000 --> 00:11:04,880 And that makes it really easy to add or remove stuff being executed around. 203 00:11:04,880 --> 00:11:07,960 This is a really common pattern for managing resources. 204 00:11:07,960 --> 00:11:12,200 So let's look at one more example of this that's built into Ruby. 205 00:11:12,200 --> 00:11:16,960 Yeah, you'll often want to open up a file, do something with its contents, and then ensure 206 00:11:16,960 --> 00:11:19,880 that the file is closed when you're all done with the file. 207 00:11:19,880 --> 00:11:22,280 And Ruby's got you covered. 208 00:11:22,280 --> 00:11:25,280 Okay, and Ruby, you can write and read a file like this. 209 00:11:25,280 --> 00:11:30,400 You can call the open method on the file class, pass in a file name, and a mode. 210 00:11:30,400 --> 00:11:32,320 In this case, we're writing to the file. 211 00:11:32,320 --> 00:11:36,520 We get back an open file object, in this case, it's in the variable F. 212 00:11:36,520 --> 00:11:40,840 And then we can just use puts on that F object that print out some strings to that file, 213 00:11:40,840 --> 00:11:43,280 and at the end, we need to make sure to close it. 214 00:11:43,280 --> 00:11:46,400 When you turn around and want to read the file, you open the file with the file name, 215 00:11:46,400 --> 00:11:50,840 and the mode is now set to R, which is reading, you get back an open file object again. 216 00:11:50,840 --> 00:11:52,280 We can iterate through the file. 217 00:11:52,280 --> 00:11:56,880 This is an example of each on a file object, gives you each line, which is pretty cool. 218 00:11:56,880 --> 00:11:59,440 And then you've got to remember to close the file when you're done. 219 00:11:59,440 --> 00:12:03,040 So if we run this, it wrote to a file, and then it read it back in again, 220 00:12:03,040 --> 00:12:07,000 and it just prints out, hello, and goodbye, which are the contents of that file. 221 00:12:07,000 --> 00:12:10,720 So this works, but it has the same problem that we ran into with the gateway. 222 00:12:10,720 --> 00:12:14,040 We have to remember to close the file when we're done. 223 00:12:14,040 --> 00:12:18,720 But conveniently, the open method is designed to optionally take a block, 224 00:12:18,720 --> 00:12:22,400 and using it with a block makes it a lot less prone to error. 225 00:12:22,400 --> 00:12:26,240 So the way to do that is instead of getting back a file object like that, 226 00:12:26,240 --> 00:12:30,680 we can associate a block with the open method, and we're going to get a block parameter. 227 00:12:30,680 --> 00:12:32,880 It's going to be the file object itself. 228 00:12:32,880 --> 00:12:37,360 Then inside of the block, we can use that F object, print out our strings, 229 00:12:37,360 --> 00:12:41,840 and we don't have to remember to close it, because that's going to be handled by the open method for us. 230 00:12:41,840 --> 00:12:43,240 So we just end the block. 231 00:12:43,240 --> 00:12:48,240 In the same way when we're reading, we can give it a block parameter, and a block there, 232 00:12:48,240 --> 00:12:52,240 inside of the block will read those things, and we don't have to close it at the end. 233 00:12:52,240 --> 00:12:56,800 So the responsibility for closing an open file has shifted from you, the coder, 234 00:12:56,800 --> 00:13:00,080 to the file objects themselves, which is really nice. 235 00:13:00,080 --> 00:13:05,440 So just for fun, how might we implement a file that open in its simplest form? 236 00:13:05,440 --> 00:13:09,520 Well, let's go ahead and change the occurrences of open here to my open. 237 00:13:09,520 --> 00:13:12,480 We're going to write our own version of this. 238 00:13:12,480 --> 00:13:18,480 We know these are defined inside of the file class, so let's go ahead and reopen Ruby's file class. 239 00:13:18,480 --> 00:13:22,400 The method is a class method we're calling on the class is going to be self-dot, 240 00:13:22,400 --> 00:13:24,880 and this can be called my open. 241 00:13:24,880 --> 00:13:26,320 All right, it takes some parameters. 242 00:13:26,320 --> 00:13:30,800 The first parameter is the file name, and the second parameter is the mode. 243 00:13:30,800 --> 00:13:33,440 All right, what's the first thing we need to do inside of here? 244 00:13:33,440 --> 00:13:36,080 Well, we need to create a new file that's open. 245 00:13:36,080 --> 00:13:41,680 Why we do that is we call file.new, pass in the file name, or just go ahead and 246 00:13:41,680 --> 00:13:43,360 delegate that down to that method. 247 00:13:43,360 --> 00:13:48,240 File.new actually opens the file and returns a new file handle or file object. 248 00:13:48,240 --> 00:13:52,320 Oh, and as a small little refinement here, you can use self because inside of the 249 00:13:52,320 --> 00:13:56,640 class method, self is going to refer to the file class itself in this case. 250 00:13:57,760 --> 00:14:02,560 Last thing we need to do, we know, is to close the file in between those two things. 251 00:14:02,560 --> 00:14:06,640 We need to yield to the block and give the block the file as a block parameter. 252 00:14:07,520 --> 00:14:13,840 Okay, that's a pretty good start, but what happens if a block isn't given to this my open method? 253 00:14:13,840 --> 00:14:18,400 Well, what we want to do there is just simply return the file objects. 254 00:14:18,400 --> 00:14:22,080 Say, return the file unless a block is given. 255 00:14:23,760 --> 00:14:29,520 That way we can use file.open or file.myopen, just as we did when we started out by getting back a 256 00:14:29,520 --> 00:14:33,440 file object, doing what we want with it, and then taking care of closing it ourselves. 257 00:14:34,160 --> 00:14:36,400 Of course, we also need to handle exceptions. 258 00:14:37,040 --> 00:14:41,840 In particular, we need to make sure that the file is always closed, whether the block 259 00:14:41,840 --> 00:14:45,120 raises it and exception or not, and we learned how to do that earlier. 260 00:14:45,120 --> 00:14:48,160 We want to scope it to just this line of code so we're going to say begin. 261 00:14:49,840 --> 00:14:55,840 Yield to the block and then ensure that the file object is closed at the very end there. 262 00:14:56,480 --> 00:15:00,000 Now, in this particular case, there's no rescue clause, so any exceptions are going to 263 00:15:00,000 --> 00:15:04,640 get propagated to the code that calls open, which is in a better position to handle it anyway. 264 00:15:05,200 --> 00:15:08,880 All right, if we save that, but we run it, we get the same result. 265 00:15:08,880 --> 00:15:14,560 So we basically re-implemented the open method using the techniques we've learned throughout this course. 266 00:15:15,120 --> 00:15:15,760 Pretty cool. 267 00:15:16,480 --> 00:15:20,400 So these examples pull together a lot of things we learned throughout this course. 268 00:15:20,720 --> 00:15:24,800 Yeah, and hopefully you recognize some recurring patterns in all these examples. 269 00:15:24,800 --> 00:15:43,359 And in the exercise that follows, you'll find some more examples to practice resource management with blocks. 25490

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