Курс Raku / Об’єкти, введення-виведення та винятки / Винятки / Власні винятки / Вправи / Помилка від’ємного числа
Розв’язання: Помилка від’ємного числа
Ось один із можливих варіантів розв’язання задачі.
Код
class Negative is Exception {
has $.n;
method message {
"$.n is negative";
}
}
sub check($n) {
Negative.new(n => $n).throw if $n < 0;
return $n;
}
{
say check(-5);
CATCH {
when Negative {
say .message;
}
}
}
Negative.new(n => -10).throw;🦋 Вихідний код можна знайти у файлі negative-error.raku.
Вивід
-5 is negative
-10 is negative
in block <unit> at negative-error.raku line 24Коментарі
Negative is Exceptionробить клас придатним для кидання, а його методmessageвикористовує атрибутn, щоб побудувати текст.checkперевіряє свій ввід і кидає власний виняток для від’ємного числа. Виняток мандрує зcheckдоCATCHу блоці, що викликав, деwhen Negativeзіставляється з ним за типом і виводить повідомлення. Перевірка вводу й сигналізування про погані значення типізованим винятком є дуже поширеним, справжнім застосуванням власних винятків.Дужки
{ … }навколо виклику потрібні тому, що фазерCATCHобробляє винятки, кинуті в його власному обгортальному блоці. Блок групує ризикованийcheck(-5)разом ізCATCH, який його охороняє, тож кинутий виняток перехоплюється саме тут, і виконання відновлюється одразу після блоку. Без загортання їх у блокCATCHохороняв би натомість усю програму — і, перехопивши виняток, програма просто завершилася б, не маючи природного місця, щоб продовжити.Останній
Negative.new(n => -10).throwпоказує зворотний бік. Він стоїть поза блоком, тож його ніхто не перехоплює: виняток поширюється аж до верху, і програма гине, виводячи повідомлення й трасування стека до стандартного потоку помилок і завершуючись із ненульовим статусом. Така типова доля будь-якого неперехопленого винятку — і саме тому першому киданню потрібен бувCATCH, щоб вижити.