是否应该在“抛出”之后严格调用“ CATCH”?
示例1:
const returnVal = [["Christ", "Evans", "Male", 1982], ["Robert", "Downey", "Male"]].map(person => {
return {
firstName: person[0],
lastName: person[1],
gender: person[2],
age: person[3] === undefined ? "Invalid Birth Year": person[3]
};
错误:
找不到方法“接收器”:没有方法缓存,也没有。^ find_method 在/tmp/739536251/main.pl6第11行处阻止
示例2:
say 'Hello World!';
class E is Exception { method message() { "Just stop already!" } }
CATCH {
when E {
.resume;
}
}
E.new.throw;
没有错误
答案 0 :(得分:4)
CATCH
必须在同一块中。
第一个示例中的问题是没有E
,而是引发了另一个异常。试试
class E is Exception { method message() { "Just stop already!" } };
CATCH {
when E {
.resume;
}
default { say .perl }
}
E.new.throw;
您可以更改when
块
class E is Exception { method message() { "Just stop already!" } };
CATCH {
when E {
say .message;
}
}
E.new.throw;
或类E
的定义,例如
class E is Exception {
has $.resume;
method message() { "Just stop already!" }
};
CATCH {
when E {
say .resume;
}
}
E.new(resume => 'stop here').throw;
答案 1 :(得分:4)
是an already filed .resume
bug。
该错误消息并不是P6产生的最出色的消息,但从技术上来说并不是LTA,因为它是描述性的,并且与错误相关(由错误引起)。
捕获并引发自定义异常
我认为这只是一个.resume
错误,而不是关于自定义异常的问题。
是否应该在“抛出”之后严格调用“ CATCH”?
不,那不是问题。 (也就是说,将其放在.throw
之后只是为了避免此错误;我稍后会再讨论。)
在蓬勃发展的代码中,您引发异常,然后.resume
对此作出响应。根据文档.resume
:
在
.throw
离开的地方恢复控制流
在这种情况下,这意味着箭头所指的位置:
E.new.throw ;
?
现在,考虑以下程序:
42;
如果您运行该程序,则会看到:
Useless use of constant integer 42 in sink context (line 1)
这是因为P6在决定语句末尾的操作时会应用"sink context"规则。应用接收器上下文需要对语句产生的值调用.sink
。对于42
,.sink
方法会生成“无用”警告。
但是.resume
引发的异常的值是什么?
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
块放在之后会有所不同?
似乎错误仅在throw语句为 last 语句时发生。正常工作,只显示42
:
class E is Exception {}
CATCH { when E { .resume } }
E.new.throw;
say 42;
您大概知道,P6特别对待块的最后一条语句。也许这个错误与此有关。