Это уже поданная .resume
ошибка .
Сообщение об ошибке не самое удивительное, которое когда-либо производил P6, но технически оно не LTA потому что он описательный и связан с ошибкой (вызванной ошибкой).
CATCH и выбрасывание пользовательского исключения
Я думаю, что это просто.resume
ошибка, а не о пользовательских исключениях.
Должен ли 'CATCH' вызываться строго после 'throw'?
Нет, это не проблема.(Тем не менее, поместив его после .throw
просто так, чтобы избежать этой ошибки; я вернусь к этому позже.)
В коде, который идет бум, вы бросаете исключение, затем.resume
в ответ на это.Согласно документу .resume
:
Возобновляет поток управления, где .throw
оставил его
Что в данном случае означает, куда указывает стрелка:
E.new.throw ;
?
Теперь рассмотрим эту программу:
42;
Если вы запустите эту программу, вы увидите:
Useless use of constant integer 42 in sink context (line 1)
Это потому, что P6 применяет "контекст приемника" правила при принятии решения, что делать в конце заявления.Применение контекста приемника влечет за собой вызов .sink
для значения, созданного оператором.А для 42
метод .sink
генерирует «бесполезное» предупреждение.
Но каково значение .resume
d брошенного исключения?
class E is Exception {}
CATCH { when E { .resume } }
say E.new.throw.^name; # BOOTException
E.new.throw.sink; # Cannot find method 'sink': no method cache and no .^find_method
Оказывается, этоBOOTException
объект, который не является объектом высокого уровня P6, но является объектом низкого уровня VM, объект, у которого нет метода .sink
(а также блокирует резервные методы P6 для нахождения метода, следовательно, «Я перепробовал все»"сообщение об ошибке).
Так почему же установка CATCH
block после throw имеет значение?
Кажется, ошибка возникает, только еслиоператор throw является оператором last .Это прекрасно работает, просто отображая 42
:
class E is Exception {}
CATCH { when E { .resume } }
E.new.throw;
say 42;
Как вы, вероятно, знаете, P6 обрабатывает последний оператор блока специально.Возможно, эта ошибка связана с этим.