Raku程序编译和执行的顺序(也许是嵌套编译阶段?



以下程序无法正确编译:

sub f(Int $a) { my Str $b = $a }
say f 42;
say f 'foo';

具体来说,第 3 行会导致编译错误(带有===SORRY!===错误消息);此错误发生在执行第 2 行之前,因此永远不会达到 &f 中的类型不匹配。

但是,具体来说,此错误何时发生? 我以为它发生在 CHECK 阶段,但惊讶地注意到raku -c不会生成编译错误;它报告Syntax OK.

为了更深入地研究这一点,我在上面的代码片段中添加了日志记录代码:

BEGIN note 'begin';
CHECK note 'check';
INIT  note 'init';
END   note 'end';
sub f(Int $a) { my Str $b = $a }
say f 42;
say f 'foo';

运行此修订后的代码raku -c打印"begin check 语法正常";运行此修订后的代码raku打印"begin check ===SORRY!==="(以及错误消息的其余部分)。

如果我删除say f 'foo'行(因此出现编译错误),raku -c仍然打印"begin check 语法正常",但raku打印"begin check init 类型检查失败... 结束"(再次省略错误消息的正文)。

这是怎么回事? 生成===SORRY!===的编译错误是否发生在 CHECK 和 INIT之间的某个时间(有这样的时间吗? 还是raku -c实际上并没有像raku --help所指示的那样"运行 BEGIN 和 CHECK 块"? 还是别的什么?

相关:如果有的话,这些与"嵌套编译时间"的想法有什么联系? 此代码的执行是否涉及任何嵌套编译时间,或者仅在使用模块时发生? 有没有办法记录/记录单独的编译阶段(也许使用正确放置的 BEGIN 块?)还是没有公开的东西?

SORRY 消息是静态优化器的副作用。 观察以下各项之间的行为差异:

$ raku -e 'sub foo(Int $a) { }; foo "foo"'
===SORRY!=== Error while compiling -e
Calling foo(Str) will never work with declared signature (Int $a)

和:

$ raku --optimize=off -e 'sub foo(Int $a) { }; foo "foo"'
Type check failed in binding to parameter '$a'; expected Int but got Str ("foo")
in sub foo at -e line 1

这发生在CHECKINIT时间之间,除非它已被禁用。 请注意,禁用静态优化器会使其成为运行时错误。

最新更新