Raku 程序编译和执行的顺序(可能是嵌套的编译阶段?)
Sequence of Raku program compilation and execution (maybe nested compile phases?)
以下程序正确编译失败:
sub f(Int $a) { my Str $b = $a }
say f 42;
say f 'foo';
具体来说,第 3 行导致编译错误(带有 ===SORRY!===
错误消息);此错误发生在第 2 行执行之前,因此从未达到 &f 中的类型不匹配。
但是这个错误具体是什么时候发生的?我以为它发生在 CHECK phase 期间,但惊讶地发现 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\n check\n Syntax OK”; 运行使用 raku
打印“begin\n check\n ===SORRY!===”(以及错误消息的其余部分)。
如果我删除 say f 'foo'
行(因此会出现编译错误),raku -c
仍会打印“begin\n check\n Syntax OK”,但 raku
打印“begin\n check\n init\n 类型检查失败...\n 结束”(再次省略错误消息的正文)。
这是怎么回事?生成 ===SORRY!===
的编译错误是否发生在 在 CHECK 和 INIT 之间的某个时间(有这样的时间吗?)?或者 raku -c
实际上不是 raku --help
表示的“运行 BEGIN 和 CHECK 块”?或者别的什么?
相关:如果有的话,这与“嵌套编译时间”的想法有何联系?此代码的执行是否涉及任何嵌套的编译时间,或者仅在使用模块时才会发生?有没有什么方法可以 note/log 分开编译阶段(可能是正确放置 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
这发生在 CHECK
和 INIT
时间之间,除非它已被禁用。请注意,禁用静态优化器会导致运行时错误。
以下程序正确编译失败:
sub f(Int $a) { my Str $b = $a }
say f 42;
say f 'foo';
具体来说,第 3 行导致编译错误(带有 ===SORRY!===
错误消息);此错误发生在第 2 行执行之前,因此从未达到 &f 中的类型不匹配。
但是这个错误具体是什么时候发生的?我以为它发生在 CHECK phase 期间,但惊讶地发现 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\n check\n Syntax OK”; 运行使用 raku
打印“begin\n check\n ===SORRY!===”(以及错误消息的其余部分)。
如果我删除 say f 'foo'
行(因此会出现编译错误),raku -c
仍会打印“begin\n check\n Syntax OK”,但 raku
打印“begin\n check\n init\n 类型检查失败...\n 结束”(再次省略错误消息的正文)。
这是怎么回事?生成 ===SORRY!===
的编译错误是否发生在 在 CHECK 和 INIT 之间的某个时间(有这样的时间吗?)?或者 raku -c
实际上不是 raku --help
表示的“运行 BEGIN 和 CHECK 块”?或者别的什么?
相关:如果有的话,这与“嵌套编译时间”的想法有何联系?此代码的执行是否涉及任何嵌套的编译时间,或者仅在使用模块时才会发生?有没有什么方法可以 note/log 分开编译阶段(可能是正确放置 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
这发生在 CHECK
和 INIT
时间之间,除非它已被禁用。请注意,禁用静态优化器会导致运行时错误。