All language subtitles for pragstudio-ruby-blocks-07-toggle-around (Transcribed on 27-Apr-2023 21-07-02)

af Afrikaans
ak Akan
sq Albanian
am Amharic
ar Arabic
hy Armenian
az Azerbaijani
eu Basque
be Belarusian
bem Bemba
bn Bengali
bh Bihari
bs Bosnian
br Breton
bg Bulgarian
km Cambodian
ca Catalan
ceb Cebuano
chr Cherokee
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
ee Ewe
fo Faroese
tl Filipino
fi Finnish
fr French
fy Frisian
gaa Ga
gl Galician
ka Georgian
de German
el Greek
gn Guarani
gu Gujarati
ht Haitian Creole
ha Hausa
haw Hawaiian
iw Hebrew
hi Hindi
hmn Hmong
hu Hungarian
is Icelandic
ig Igbo
id Indonesian
ia Interlingua
ga Irish
it Italian
ja Japanese
jw Javanese
kn Kannada
kk Kazakh
rw Kinyarwanda
rn Kirundi
kg Kongo
ko Korean
kri Krio (Sierra Leone)
ku Kurdish
ckb Kurdish (Soranî)
ky Kyrgyz
lo Laothian
la Latin
lv Latvian
ln Lingala
lt Lithuanian
loz Lozi
lg Luganda
ach Luo
lb Luxembourgish
mk Macedonian
mg Malagasy
ms Malay
ml Malayalam
mt Maltese
mi Maori
mr Marathi
mfe Mauritian Creole
mo Moldavian
mn Mongolian
my Myanmar (Burmese)
sr-ME Montenegrin
ne Nepali
pcm Nigerian Pidgin
nso Northern Sotho
no Norwegian
nn Norwegian (Nynorsk)
oc Occitan
or Oriya
om Oromo
ps Pashto
fa Persian
pl Polish
pt-BR Portuguese (Brazil)
pt Portuguese (Portugal)
pa Punjabi
qu Quechua
ro Romanian
rm Romansh
nyn Runyakitara
ru Russian
sm Samoan
gd Scots Gaelic
sr Serbian
sh Serbo-Croatian
st Sesotho
tn Setswana
crs Seychellois Creole
sn Shona
sd Sindhi
si Sinhalese
sk Slovak
sl Slovenian
so Somali
es Spanish
es-419 Spanish (Latin American)
su Sundanese
sw Swahili
sv Swedish
tg Tajik
ta Tamil
tt Tatar
te Telugu
th Thai
ti Tigrinya
to Tonga
lua Tshiluba
tum Tumbuka
tr Turkish
tk Turkmen
tw Twi
ug Uighur
uk Ukrainian
ur Urdu
uz Uzbek
vi Vietnamese
cy Welsh
wo Wolof
xh Xhosa
yi Yiddish
yo Yoruba
zu Zulu

Original subtitles

So let's build on this executor round pattern with a slight variation.

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.

So here's an example of that.

Let's suppose we have this phone class.

And a phone can be put in airplane mode.

Let's say it's fault, so it's turned off by default.

If we want to send a text, then we call the text method passing in the message.

When it's in airplane mode, text messages are saved rather than being sent.

So if we have a phone object down here and we call the text method,

well airplane mode is turned off by default, so if we run this, it says send the text just landed.

Okay, so let's send some text while we're in airplane mode, like just took off.

Yeah, so one way to do that, I'm going to do it right above here.

Got some code already prepared.

Would be to put the phone in airplane mode by setting airplane mode attribute to true.

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.

If we run this, well you see that the two messages that were sent when it was in airplane mode were just saved.

And then because we'd set it back to false at the end, it sent the last text as it did before.

Okay, that works, but it's prone to error because we have to remember to reset airplane mode to its default, false.

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.

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.

And this time I'm going to put the method inside the phone class.

It'll be an instance method.

And it's going to be called in airplane mode.

What's it going to do? Well the first thing it's going to do is put us in airplane mode.

We have an instance variable airplane mode because we're inside of an instance method here.

We're going to set it to true.

And then we want to make sure at the end we set airplane mode back to its default, which is false.

Between those two statements, we actually want to run our block.

We do that by calling yield. Okay, now down here outside of our class, we can call phone in airplane mode.

This takes a block. So we take these two things.

We want to run those inside the block.

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.

And we're already bracketed by turning airplane mode on and turning airplane mode off again.

If we run that, what we get the same output, two texts were saved.

And then one at the end was actually sent out because airplane mode got set back to false when this block was done executing.

So then we can really do anything we want inside this block.

We could try to call while we're in airplane mode.

Or we could try to send an email while we're in airplane mode.

Sure, anything we do inside of that method, we know is in airplane mode.

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.

Now, obviously when you turn airplane mode off, it should send the text messages.

You sent while you were in the air, but that's a different feature for a different day.

More important, we need to handle exceptions here.

Right. So what happens when something goes wrong inside our block?

Well, we can simulate something going wrong by simply raising an exception inside of here inside of this block.

And we'll just give it a message. I'll just say, whoops.

Now, this is going to raise a generic runtime error exception in Ruby with this string whoops here.

So if we run it now, well, we don't catch the exception.

So it ripples all the way up to the top of the program.

And we see we got a runtime error. We see it right there.

And it printed out whoops.

So what happened is right when this line of code was raised execution stopped.

So when we're yielding right here, it yielded to the block, the block began running, ran that line, ran that line,

and then raised the exception.

Nobody's handling the exception. So we never get to this line.

In fact, if I run that again, just to look at it, we see after the errors printed,

or before the errors printed, it saved the two texts, but we never see that it sent that very last text

because this line of code wasn't run.

So we need to gracefully handle or trap exceptions.

Now we can catch the exception using a rescue clause up in here in our in airplane mode method.

We just say rescue and what type of exception we want to rescue,

well, we give it a class.

This is going to be the exception class, which will basically handle all exceptions in Ruby.

And I'm going to sign it to a variable using this equal greater than syntax.

The variable is going to be called E.

And that way inside of this rescue clause, I can print out the message that was associated with

that exception.

And by rescuing this exception here, it won't ripple all the way to the top of the program,

we're just going to print out the message.

So if I run it now, we see that it saved the two texts, then it printed out the exception message there,

and then we got to our final line that just landed text.

But there's a problem here.

Notice it says it saved the text.

It didn't actually send it out.

Well, why is that?

Well, looking back in our code here,

we called yield, this calls the block yields to the block and these two statements run,

and then the exception is raised.

When the exception is raised, remember, we're part of yield here,

it skips this line completely, goes right into the rescue clause.

So what happened is we never set our airplane mode back to false again.

So then when we go to send the text down here, we're still in airplane mode,

because we haven't reset it to false,

and so it saved that text message.

So simply adding a rescue clause doesn't solve our problem completely.

We need to ensure our guarantee that airplane mode is always set back to false,

regardless of whether an exception is raised.

And we can do that very simply in Ruby by using an ensure clause here.

We say, ensure, and then anything we put inside of this clause will always get run,

regardless of whether an exception was raised or not.

What do we want to have happen here?

Well, it needs to set the airplane mode back to false.

So we slide that down into here.

So here's our method.

Set it to true.

Yield, if an exception is raised, go ahead and print it out.

But always run this line of code.

So that's always set back to false again.

In fact, I'm going to add a little bit of debugging here.

I'm going to say, mode is now, just so we can see what's printed out.

Make sure that it's getting reset.

Okay, now when we run the code,

we save the two texts, our exception is raised,

but notice that mode is now false.

It's set back to false.

And our last text message was actually sent as we would expect.

So even though an exception was raised here,

this line of code got run as well as this line of code.

So the insure clause is your friend for these sorts of scenarios.

Now, it's important to point out that you don't have to rescue the exception here.

If there's no way to really handle it when you're inside of this method,

then you can just drop that clause completely.

But you do need to have an insure clause here

to make sure you're setting airplane mode back to false.

And by not handling the exception with the rescue,

we're just assuming that that exception will get handle it

some higher level in our program.

This is another really common pattern,

and you'll see more examples of this in the exercise.

Next up, we're going to look at a use of blocks that may actually surprise you.

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