1. Features of working with variables and literals in Perl62. Perl6 - Operations on Variables, Anonymous Blocks3. Perl6 - Conditional Operators, Loops4. Perl6 - Working with Functions5. Perl6 - Classes6. Perl6 - I / O Modules7. Perl6 - Comments, whitespace, parentheses8. Perl6 - Operator Overloading9. Perl6 - Working with Data TypesIn the last article I gave a hint about catching exceptions. The few scripts that encountered the exceptions survived, and too many of my scripts died at their hands. Perhaps it is time to arrange a hunt for them. For those who are interested, what we will catch them - we meet under the cut.
And so, we have the following piece of code:
sub Func($a) { my $temp = $a*2; } Func "Test";
As you might have guessed, we will get an exception when trying to get a decimal number from the string "Test".
To add an exception handler, we need to add the following construct:
sub Func($a) { my $temp = $a*2; say "Test work"; CATCH { default { say "Something is wrong!"; } } } Func "Test"; say "Another test work";
')
Unlike the same with ++, in the sixth pearl an exception handling block is added inside that block where an exception can occur. Thus, when executing this script, we get the output:
Something is wrong! Another test work
In other words, the block in which an exception occurs stops its work (and it’s certainly a bit wrong to say so, but let's talk about this later), and the CATCH block begins to work, in which the output of the string Something is wrong. After executing the CATCH block, the script continues execution starting with the next command following the block in which the exception occurred. That is why we do not see on the screen the inscription "Test work".
In fact, our CATCH block is an ordinary “switch”. And we can add the following:
sub Func($a) { my $temp = $a*2; say "Test work"; CATCH { when X::Syntax::Name::Null { say "I will never say it =("; } default { say "Something is wrong! "~$_.WHAT.gist; } } } Func "Test"; say "Another test work";
However, the text for the exceptions we have chosen is “I will never say that.” This is because, in our case, the function does not perform such actions in which this exception would arise. All the same, to understand what kind of exception we come across, I added
"$_.WHAT.gist"
. When entering the CATCH block, the exception object caught by us is entered into the $ _ variable. Then we take its type object'a and bring it to a string (.gist function for debug, allowing you to look at the interior of the object, I will not describe it here).
Thus, we now get the following conclusion:
Something is wrong! (X::Str::Numeric) Another test work
Now we know what kind of exception is caught. We copy his name and go to see the description of our exception in the
Synopsis . (
Here is a direct link to our exception ). Then we can add one more when block:
sub Func($a) { my $temp = $a*2; say "Test work"; CATCH { when X::Syntax::Name::Null { say "I will never say it =("; } when X::Str::Numeric { say "String convertation error!"; } default { say "Something is wrong! "~$_.WHAT.gist; } } } Func "Test"; say "Another test work";
As a result, we will see the conclusion:
String convertation error! Another test work
Naturally, we can refer to all fields of the object through the $ _ variable. Fields again look in the description of the exception.
- Uff, something I'm tired of hunting, maybe we will set traps, but take a breather?
There is also a special try {} block, within which there is an “invisible” CATCH block, and if an exception occurs inside this block, the script will not stop working, and execution will continue with the next instruction after this block itself. Thus, you can simply ignore all the exceptions that we come across.
However, no one forbids you to add your CATCH inside this block, which will simply overwrite the existing one in it. The point in using your own CATCH block inside try is to simply visually show that an exception can occur inside this block. Other side effects are not observed.
-And if you try to escape?
It is quite possible that during the processing of one exception, we can get one more. However, it is worth noting that the when or default block in which the processing takes place are the most common blocks, inside which again you can put the CATCH block:
sub Func($a) { try { my $temp = $a*2; say "Test work"; CATCH { when X::Str::Numeric { die "test"; CATCH { default { say "Another die action"; } } } default { say "Something is wrong! "~$_.WHAT.gist; } } } } Func "Test"; say "Another test work";
-And let's try to tame a couple of exceptions?
Perhaps we have a couple of ways to create an exception yourself:
The first way is as you have already noticed the 'die' operator:
{ die "I'm diying..."; CATCH { default { say "I will save you!"; } } }
The second way is to call the throw method:
{ X::Str::Numeric.throw; CATCH { default { say "More exception!?!"; } } }
It is also worth noting that it is possible to inherit our class from the class of the exception, as a result of which we can create our own exceptions, but for the time being we’ll do without examples.
On this, I would like to finish my little guide on survival in the cruel world of exceptions. I hope you are interested.