Система помилок у Factor складається з трьох частин: throw, щоб сигналізувати про помилку, recover, щоб її опрацювати, і ERROR:, щоб визначити власний різновид помилки.
throwthrow (з kernel) породжує помилку. Аргументом може бути будь-яке значення: рядок тексту (англ. string), число або кортеж. Саме воно й стає помилкою, яку потім можна оглянути:
! DOCTEST: SKIP
"file not found" throw
throw не повертає керування; решту поточного слова пропущено.
recoverrecover (з continuations) виконує роль try/catch у Factor. Він приймає try-quotation і recovery-quotation:
recover ( try recovery -- )
Якщо try завершується, не породивши помилки, recovery ігнорується. Якщо try породжує помилку, ця помилка кладеться на стек, і запускається recovery:
[ "boom" throw ] [ drop "caught" ] recover .
! => "caught"
[ "ok" ] [ drop "never runs" ] recover .
! => "ok"
when із kernel - природний супутник: він запускає quotation лише тоді, коли значення на вершині стека правдиве:
: check-positive ( n -- )
0 < [ "negative!" throw ] when ;
ERROR:ERROR: визначає клас кортежу і слово, яке створює новий примірник і породжує його:
! DOCTEST: SKIP
ERROR: not-found path ;
"/missing" not-found
! throws T{ not-found { path "/missing" } }
Помилка без слотів - це просто ERROR: name ;; виклик name породжує порожній примірник. Кортежі, визначені з ERROR:, мають предикат класу name?, який можна використати, щоб перевірити, чи була перехоплена помилка саме цього типу.
Перехоплена помилка - це просто кортеж, тож кожен слот, оголошений у ERROR:, має такий самий автоматично згенерований читач slot>>, як і будь-який інший кортеж.
! DOCTEST: SKIP
{
T{ not-found { path "/a" } }
T{ not-found { path "/b" } }
}
[ path>> ] map . ! => { "/a" "/b" }
Олена, нова керівниця відділу якості на газетній фабриці, просить нас написати невелику програму для стеження за виробничим цехом.
Визначте клас кортежу помилки machine-error за допомогою слова розбору ERROR:. Йому не потрібні слоти.
machine-error ! throws a fresh machine-error
Визначте check-humidity. Воно приймає зі стека показник вологості й викликає throw зі рядком "humidity too high", коли цей показник строго більший за 70. Інакше воно нічого не повертає.
50 check-humidity ! returns nothing
80 check-humidity ! throws "humidity too high"
Визначте check-temperature. Воно приймає показник температури й викликає throw зі рядком "temperature too high", коли цей показник строго більший за 500. Інакше воно нічого не повертає.
400 check-temperature ! returns nothing
600 check-temperature ! throws "temperature too high"
Визначте monitor, щоб воно приймало зі стека вологість і температуру та виконувало обидві перевірки. Якщо будь-яка з перевірок викликає throw, monitor натомість має викликати throw з новим machine-error. Якщо обидві перевірки проходять, monitor нічого не повертає.
50 400 monitor ! returns nothing
80 400 monitor ! throws a machine-error
50 600 monitor ! throws a machine-error
Визначте monitor-batch, щоб воно приймало масив показників { humidity temperature } і повертало, скільки з них провалилися б (тобто скільки змусили б monitor викликати throw).
{ { 50 400 } { 80 400 } { 50 600 } { 60 200 } } monitor-batch .
! => 2
Зареєструйтеся на Exercism, щоб вивчати й опановувати Factor, а також 47 концепцій163 вправи та справжнє наставництво від людей, і все це безкоштовно.