Меня немного смущает обработка ошибок в Rebol. Имеет конструкции БРОСА и ЗАХВАТА:
>> repeat x 10 [if x = 9 [throw "Nine!"]]
** Throw error: no catch for throw: make error! 2
>> catch [repeat x 10 [if x = 9 [throw "Nine!"]]]
== "Nine!"
Но этот бросок и захват не связаны с обработчиком, переданным в уточнение / EXCEPT в TRY:
>> try/except [throw "Nine!"] [print "Exception handled!"]
** Throw error: no catch for throw: make error! 2
Это очень характерно для типа ошибки Rebol:
>> try/except [print 1 / 0] [print "Error handled!"]
Error handled!
Если вы хотите, вы можете запускать свои собственные ошибки, но не используя THROW, как на других языках. Выдача ошибок просто приведет к жалобе на то, что вас не поймают, как и любой другой тип значения:
>> try/except [throw make error! "Error string"] [print "Error handled!"]
** Throw error: no catch for throw: make error! 2
Вы должны СДЕЛАТЬ их, чтобы оценщик попытался выполнить что-то типа error! вызвать то, что он считает "исключением":
>> try/except [do make error! "Error string"] [print "Error handled!"]
Error handled!
(Примечание: вы можете использовать заранее подготовленные ошибки, очевидно, например cause-error 'Script 'invalid-type function!
- подробнее см. system/catalog/errors
.)
Если вы не укажете уточнение / EXCEPT, вы сможете получать любые ошибки в качестве значения. Однако это, похоже, делает невозможным различить, была ли вызвана ошибка или нет:
>> probe try [do make error! "Some error"]
make error! [
code: 800
type: 'User
id: 'message
arg1: "some error"
arg2: none
arg3: none
near: none
where: none
]
** User error: "Some error"
>> probe try [make error! "Some error"]
make error! [
code: 800
type: 'User
id: 'message
arg1: "Some error"
arg2: none
arg3: none
near: none
where: none
]
** User error: "Some error"
Казалось бы, в CATCH такое же отсутствие различий между возвратом значения и выдачей значения. Но есть способ обойти это с помощью «именованных бросков»:
>> code: [repeat x 10 [if x = 9 [throw/name "Nine!" 'number]]]
>> catch/name [do code] 'number
== "Nine!"
>> catch/name [do code] 'somethingelse
** Throw error: no catch for throw: make error! 2
Итак, теперь вопросы:
Есть ли практическая ценность в этом разделении? Как решить, использовать ли THROW и CATCH или DO ошибки и обработать это с помощью TRY / EXCEPT?
Есть ли у этого различия прецедент в других языках, и было бы лучше назвать / EXCEPT / ON-ERROR или что-то в этом роде?
Почему написано
"no catch for throw: make error! 2"
вместо чего-то более информативного? Что такоеmake error! 2
?