Reader small image

You're reading from  Perl 6 Deep Dive

Product typeBook
Published inSep 2017
Reading LevelIntermediate
PublisherPackt
ISBN-139781787282049
Edition1st Edition
Languages
Right arrow
Author (1)
Andrew Shitov
Andrew Shitov
author image
Andrew Shitov

Andrew Shitov has been a Perl enthusiast since the end of the 1990s, and is the organizer of over 30 Perl conferences in eight countries. He worked as a developer and CTO in leading web-development companies, such as Art. Lebedev Studio, Booking dotCom, and eBay, and he learned from the "Fathers of the Russian Internet", Artemy Lebedev and Anton Nossik. Andrew has been following the Perl 6 development since its beginning in 2000. He ran a blog dedicated to the language, published a series of articles in the Pragmatic Perl magazine, and gives talks about Perl 6 at various Perl events. In 2017, he published the Perl 6 at a Glance book by DeepText, which was the first book on Perl 6 published after the first stable release of the language specification.
Read more about Andrew Shitov

Right arrow

Working with Exceptions

In the previous two chapters, we talked about object-oriented programming and about input and output, which is implemented using objects. In this chapter, we continue working with objects and will discuss another area in Perl 6, whose implementation extensively uses classes and has a vast hierarchical structure.

Exceptions are situations where the program enters such a state that it cannot run further. Some exceptions are caused by flaws in the design of a program, others happen because of external factors, such as disk failure or broken connection to a database. In this case, an exception is not something extraordinary that has to stop the program but a way to handle the error and continue execution.

In this chapter, we will talk about exceptional situations that a program can be faced with. Moreover, we will also see ways a in which programmer can prevent...

The try block

Let us start with one of the simplest exceptions, division by zero. Run the following one-liner:

say 1 / 0;

The program breaks and prints the following error message:

Attempt to divide 1 by zero using div
  in block <unit> at zero-div.pl line 1

Actually thrown at:
  in block <unit> at zero-div.pl line 1

We cannot divide by zero. Notice that the error message also contains the stack trace of the program. As we do not use any modules or have any function calls, the stack trace is short.

Now, let's do some other actions before and after the line with the division, which fails:

say 'Going to divide 1 by 0';
say 1 / 0;
say 'Division is done';

An exception because of division by zero happens at runtime. So, the program executes the first line and prints the first message. Then, an exception occurs and the program terminates. Nothing...

Soft failures

In the previous example, the try block contained the instructions for both math calculations and printing the result. In real programs, these actions are often separated. Let us re-write the program so that it divides the numbers in a separate subroutine:

my $a = prompt 'Enter dividend > ';
my $b = prompt 'Enter divisor > ';
my $c = calculate($a, $b);
say 'Now ready to print';
say "The result of $a / $b is $c.";
say 'Done.';

sub calculate($a, $b) {
    return $a / $b;
}

Now the dangerous action happens inside the calculate function and the result is used outside it.

Run the program with values that should cause exception:

$ perl6 division.pl
Enter dividend > 10
Enter divisor > 0
Now ready to print
Attempt to divide 10 by zero using div
  in block <unit> at 06.pl line 7

Actually thrown at:
  in...

The CATCH phaser

Earlier in this chapter, we used the try block to catch exceptions. If the exceptions happen inside the try block, it sets the $! variable, which you can check later.

In Perl 6, this is not the only method to handle exceptions. Let's return to the previous program but this time we'll use the CATCH block:

my $a = prompt 'Enter dividend > ';
my $b = prompt 'Enter divisor > ';
my $c = $a / $b;
say "The result of $a / $b is $c.";
say 'Done.';

CATCH {
    say 'Exception caught!';
}

Run the program:

$ perl6 division.pl
Enter dividend > 10
Enter divisor > 0
Exception caught!
Attempt to divide 10 by zero using div
  in block <unit> at 07.pl line 4

Actually thrown at:
  in block <unit> at 07.pl line 4

As soon as the division by zero happens and its result is used, the CATCH block is triggered...

The Exception object

Exceptions in Perl 6 are handled via the objects of the classes that are derived from the Exception class. These objects contain all the necessary information regarding the exception, including some text description and stack trace (in Perl 6, it is called backtrace).

Perl 6 creates an exception object when an exception arises. We have seen an example of such a situation earlier in this chapter—the error became visible during an attempt to print the result of the illegal mathematical operation. Now, let us produce an exception ourselves using the die keyword.

The die keyword throws a fatal exception and terminates the program. A typical usage is to stop the program if it cannot open a file or load a resource that is vital for the rest of the program, for example:

my $fh = open 'filename.txt' or die 'File not found';

If there is no...

The Failure object

Let us create a program that tries to open a nonexisting file and read the first line from it:

my $f = open 'dummy.txt';
say $f.get;

This program will raise an exception:

Failed to open file /Users/ash/code/exceptions/dummy.txt: no such file or directory
  in block <unit> at 14.pl line 1

Notice that the exception happens only after an attempt to read from a file happens. Simply opening a file does not create an error, it only sets the $f file handler to the Failure object.

The failure object is a wrapper around an Exception object. The exception itself is reachable via the exception method:

my $f = open 'dummy.txt';
say $f.exception;

It prints the error message:

Failed to open file /Users/ash/code/exceptions/dummy.txt: no such file or directory

You can test a failure object in the Boolean context, for example, immediately after opening...

Creating custom exceptions

In the previous sections, we have seen that exceptions in Perl 6 use the object-oriented approach, which, in particular, helps to distinguish between different exceptions in the CATCH block.

In this section, we will create a custom exception that is integrated into the Perl 6 system as smoothly as any other built-in classes in the X:: namespace. If you do not have any special requirements, create your custom exception classes in the same namespace.

For example, let us create a Lift class together with the X::Lift::Overload exception, which will be triggered when too many people enter the lift:

class Lift {
    class X::Lift::Overload is Exception {
        method message {
            'Too many people!'
        }
    }

    has $.capacity = 5;
    has $!people;
    method enter(Int $n = 1) {
        $!people += $n;
        X::Lift::Overload...

Summary

In this chapter, we learned about working with exceptions in Perl 6. We examined in detail ways to throw, catch, and hide exceptions by using different mechanisms of the language—try blocks and CATCH phasers. We talked about soft failures, which are postponed exceptions that are only thrown when it is really unavoidable. Also, we demonstrated how to use the object-oriented approach to handle exceptions of different types and how to create a custom exception.

lock icon
The rest of the chapter is locked
You have been reading a chapter from
Perl 6 Deep Dive
Published in: Sep 2017Publisher: PacktISBN-13: 9781787282049
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €14.99/month. Cancel anytime

Author (1)

author image
Andrew Shitov

Andrew Shitov has been a Perl enthusiast since the end of the 1990s, and is the organizer of over 30 Perl conferences in eight countries. He worked as a developer and CTO in leading web-development companies, such as Art. Lebedev Studio, Booking dotCom, and eBay, and he learned from the "Fathers of the Russian Internet", Artemy Lebedev and Anton Nossik. Andrew has been following the Perl 6 development since its beginning in 2000. He ran a blog dedicated to the language, published a series of articles in the Pragmatic Perl magazine, and gives talks about Perl 6 at various Perl events. In 2017, he published the Perl 6 at a Glance book by DeepText, which was the first book on Perl 6 published after the first stable release of the language specification.
Read more about Andrew Shitov