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,000
So let's build on this executor round pattern with a slight variation.
2
00:00:07,000 --> 00:00:14,000
Sometimes you want to execute around something like a toggle switch and you want to turn something on and then remember to turn something off.
3
00:00:14,000 --> 00:00:16,000
So here's an example of that.
4
00:00:16,000 --> 00:00:18,000
Let's suppose we have this phone class.
5
00:00:18,000 --> 00:00:21,000
And a phone can be put in airplane mode.
6
00:00:21,000 --> 00:00:24,000
Let's say it's fault, so it's turned off by default.
7
00:00:24,000 --> 00:00:30,000
If we want to send a text, then we call the text method passing in the message.
8
00:00:30,000 --> 00:00:36,000
When it's in airplane mode, text messages are saved rather than being sent.
9
00:00:36,000 --> 00:00:40,000
So if we have a phone object down here and we call the text method,
10
00:00:40,000 --> 00:00:46,000
well airplane mode is turned off by default, so if we run this, it says send the text just landed.
11
00:00:46,000 --> 00:00:52,000
Okay, so let's send some text while we're in airplane mode, like just took off.
12
00:00:52,000 --> 00:00:55,000
Yeah, so one way to do that, I'm going to do it right above here.
13
00:00:55,000 --> 00:00:57,000
Got some code already prepared.
14
00:00:57,000 --> 00:01:01,000
Would be to put the phone in airplane mode by setting airplane mode attribute to true.
15
00:01:01,000 --> 00:01:09,000
Then we'll send a couple of text messages and then we have to remember at the end to turn airplane mode back to which the fault, which would be false.
16
00:01:09,000 --> 00:01:15,000
If we run this, well you see that the two messages that were sent when it was in airplane mode were just saved.
17
00:01:15,000 --> 00:01:20,000
And then because we'd set it back to false at the end, it sent the last text as it did before.
18
00:01:20,000 --> 00:01:28,000
Okay, that works, but it's prone to error because we have to remember to reset airplane mode to its default, false.
19
00:01:28,000 --> 00:01:36,000
After we've run these two text messages through, otherwise we won't get the output we expect out here because we'll still be in airplane mode.
20
00:01:36,000 --> 00:01:43,000
So instead of having to remember to reset it back to its default state, let's write a method that does that remembering for us.
21
00:01:43,000 --> 00:01:46,000
And this time I'm going to put the method inside the phone class.
22
00:01:46,000 --> 00:01:47,000
It'll be an instance method.
23
00:01:47,000 --> 00:01:51,000
And it's going to be called in airplane mode.
24
00:01:51,000 --> 00:01:55,000
What's it going to do? Well the first thing it's going to do is put us in airplane mode.
25
00:01:55,000 --> 00:01:59,000
We have an instance variable airplane mode because we're inside of an instance method here.
26
00:01:59,000 --> 00:02:01,000
We're going to set it to true.
27
00:02:01,000 --> 00:02:08,000
And then we want to make sure at the end we set airplane mode back to its default, which is false.
28
00:02:08,000 --> 00:02:12,000
Between those two statements, we actually want to run our block.
29
00:02:12,000 --> 00:02:22,000
We do that by calling yield. Okay, now down here outside of our class, we can call phone in airplane mode.
30
00:02:22,000 --> 00:02:25,000
This takes a block. So we take these two things.
31
00:02:25,000 --> 00:02:27,000
We want to run those inside the block.
32
00:02:27,000 --> 00:02:35,000
We don't have to remember to do this because simply by ending the block right there, we know that these two lines will get run as part of this yield.
33
00:02:35,000 --> 00:02:41,000
And we're already bracketed by turning airplane mode on and turning airplane mode off again.
34
00:02:41,000 --> 00:02:44,000
If we run that, what we get the same output, two texts were saved.
35
00:02:44,000 --> 00:02:53,000
And then one at the end was actually sent out because airplane mode got set back to false when this block was done executing.
36
00:02:53,000 --> 00:02:56,000
So then we can really do anything we want inside this block.
37
00:02:56,000 --> 00:02:59,000
We could try to call while we're in airplane mode.
38
00:02:59,000 --> 00:03:02,000
Or we could try to send an email while we're in airplane mode.
39
00:03:02,000 --> 00:03:07,000
Sure, anything we do inside of that method, we know is in airplane mode.
40
00:03:07,000 --> 00:03:14,000
And we know it's going to be reset at the very end. So if we had call or email methods here, we could certainly call those methods as well.
41
00:03:14,000 --> 00:03:18,000
Now, obviously when you turn airplane mode off, it should send the text messages.
42
00:03:18,000 --> 00:03:23,000
You sent while you were in the air, but that's a different feature for a different day.
43
00:03:23,000 --> 00:03:26,000
More important, we need to handle exceptions here.
44
00:03:26,000 --> 00:03:30,000
Right. So what happens when something goes wrong inside our block?
45
00:03:30,000 --> 00:03:36,000
Well, we can simulate something going wrong by simply raising an exception inside of here inside of this block.
46
00:03:36,000 --> 00:03:40,000
And we'll just give it a message. I'll just say, whoops.
47
00:03:40,000 --> 00:03:46,000
Now, this is going to raise a generic runtime error exception in Ruby with this string whoops here.
48
00:03:46,000 --> 00:03:50,000
So if we run it now, well, we don't catch the exception.
49
00:03:50,000 --> 00:03:52,000
So it ripples all the way up to the top of the program.
50
00:03:52,000 --> 00:03:56,000
And we see we got a runtime error. We see it right there.
51
00:03:56,000 --> 00:03:57,000
And it printed out whoops.
52
00:03:57,000 --> 00:04:02,000
So what happened is right when this line of code was raised execution stopped.
53
00:04:02,000 --> 00:04:08,000
So when we're yielding right here, it yielded to the block, the block began running, ran that line, ran that line,
54
00:04:08,000 --> 00:04:11,000
and then raised the exception.
55
00:04:11,000 --> 00:04:14,000
Nobody's handling the exception. So we never get to this line.
56
00:04:14,000 --> 00:04:19,000
In fact, if I run that again, just to look at it, we see after the errors printed,
57
00:04:19,000 --> 00:04:24,000
or before the errors printed, it saved the two texts, but we never see that it sent that very last text
58
00:04:24,000 --> 00:04:26,000
because this line of code wasn't run.
59
00:04:26,000 --> 00:04:30,000
So we need to gracefully handle or trap exceptions.
60
00:04:30,000 --> 00:04:37,000
Now we can catch the exception using a rescue clause up in here in our in airplane mode method.
61
00:04:37,000 --> 00:04:41,000
We just say rescue and what type of exception we want to rescue,
62
00:04:41,000 --> 00:04:43,000
well, we give it a class.
63
00:04:43,000 --> 00:04:47,000
This is going to be the exception class, which will basically handle all exceptions in Ruby.
64
00:04:47,000 --> 00:04:51,000
And I'm going to sign it to a variable using this equal greater than syntax.
65
00:04:51,000 --> 00:04:53,000
The variable is going to be called E.
66
00:04:53,000 --> 00:04:59,000
And that way inside of this rescue clause, I can print out the message that was associated with
67
00:04:59,000 --> 00:05:01,000
that exception.
68
00:05:01,000 --> 00:05:05,000
And by rescuing this exception here, it won't ripple all the way to the top of the program,
69
00:05:05,000 --> 00:05:07,000
we're just going to print out the message.
70
00:05:07,000 --> 00:05:14,000
So if I run it now, we see that it saved the two texts, then it printed out the exception message there,
71
00:05:14,000 --> 00:05:18,000
and then we got to our final line that just landed text.
72
00:05:18,000 --> 00:05:19,000
But there's a problem here.
73
00:05:19,000 --> 00:05:21,000
Notice it says it saved the text.
74
00:05:21,000 --> 00:05:23,000
It didn't actually send it out.
75
00:05:23,000 --> 00:05:24,000
Well, why is that?
76
00:05:24,000 --> 00:05:26,000
Well, looking back in our code here,
77
00:05:26,000 --> 00:05:32,000
we called yield, this calls the block yields to the block and these two statements run,
78
00:05:32,000 --> 00:05:34,000
and then the exception is raised.
79
00:05:34,000 --> 00:05:37,000
When the exception is raised, remember, we're part of yield here,
80
00:05:37,000 --> 00:05:42,000
it skips this line completely, goes right into the rescue clause.
81
00:05:42,000 --> 00:05:47,000
So what happened is we never set our airplane mode back to false again.
82
00:05:47,000 --> 00:05:51,000
So then when we go to send the text down here, we're still in airplane mode,
83
00:05:51,000 --> 00:05:53,000
because we haven't reset it to false,
84
00:05:53,000 --> 00:05:55,000
and so it saved that text message.
85
00:05:55,000 --> 00:05:59,000
So simply adding a rescue clause doesn't solve our problem completely.
86
00:05:59,000 --> 00:06:05,000
We need to ensure our guarantee that airplane mode is always set back to false,
87
00:06:05,000 --> 00:06:07,000
regardless of whether an exception is raised.
88
00:06:07,000 --> 00:06:12,000
And we can do that very simply in Ruby by using an ensure clause here.
89
00:06:12,000 --> 00:06:18,000
We say, ensure, and then anything we put inside of this clause will always get run,
90
00:06:18,000 --> 00:06:21,000
regardless of whether an exception was raised or not.
91
00:06:21,000 --> 00:06:23,000
What do we want to have happen here?
92
00:06:23,000 --> 00:06:26,000
Well, it needs to set the airplane mode back to false.
93
00:06:26,000 --> 00:06:29,000
So we slide that down into here.
94
00:06:29,000 --> 00:06:30,000
So here's our method.
95
00:06:30,000 --> 00:06:31,000
Set it to true.
96
00:06:31,000 --> 00:06:35,000
Yield, if an exception is raised, go ahead and print it out.
97
00:06:35,000 --> 00:06:37,000
But always run this line of code.
98
00:06:37,000 --> 00:06:39,000
So that's always set back to false again.
99
00:06:39,000 --> 00:06:41,000
In fact, I'm going to add a little bit of debugging here.
100
00:06:41,000 --> 00:06:46,000
I'm going to say, mode is now, just so we can see what's printed out.
101
00:06:46,000 --> 00:06:48,000
Make sure that it's getting reset.
102
00:06:48,000 --> 00:06:50,000
Okay, now when we run the code,
103
00:06:50,000 --> 00:06:53,000
we save the two texts, our exception is raised,
104
00:06:53,000 --> 00:06:55,000
but notice that mode is now false.
105
00:06:55,000 --> 00:06:56,000
It's set back to false.
106
00:06:56,000 --> 00:07:01,000
And our last text message was actually sent as we would expect.
107
00:07:01,000 --> 00:07:04,000
So even though an exception was raised here,
108
00:07:04,000 --> 00:07:07,000
this line of code got run as well as this line of code.
109
00:07:07,000 --> 00:07:11,000
So the insure clause is your friend for these sorts of scenarios.
110
00:07:11,000 --> 00:07:15,000
Now, it's important to point out that you don't have to rescue the exception here.
111
00:07:15,000 --> 00:07:18,000
If there's no way to really handle it when you're inside of this method,
112
00:07:18,000 --> 00:07:21,000
then you can just drop that clause completely.
113
00:07:21,000 --> 00:07:23,000
But you do need to have an insure clause here
114
00:07:23,000 --> 00:07:26,000
to make sure you're setting airplane mode back to false.
115
00:07:26,000 --> 00:07:29,000
And by not handling the exception with the rescue,
116
00:07:29,000 --> 00:07:31,000
we're just assuming that that exception will get handle it
117
00:07:31,000 --> 00:07:33,000
some higher level in our program.
118
00:07:33,000 --> 00:07:35,000
This is another really common pattern,
119
00:07:35,000 --> 00:07:38,000
and you'll see more examples of this in the exercise.
120
00:07:38,000 --> 00:07:48,000
Next up, we're going to look at a use of blocks that may actually surprise you.
12071
Can't find what you're looking for?
Get subtitles in any language from opensubtitles.com, and translate them here.