执行包函数的意外输出

Unexpected output executing a package function

我有以下目录结构(重现问题的简化版本):

testing/
  lib/
   CLI.pm6
  t/
    01-test.t

您可以查看来源here。问题是如果你 运行 raku -Ilib t/01-test.t 你会得到以下输出:

    ok 1 - show help message
    1..1
ok 1 - no arguments provided
    not ok 1 - long version
    # Failed test 'long version'
    # at site#sources\D2E3739A3B53AD1F7CFEE6DA262613FD174A0BC9 (Test::Output) line 84
    # expected a match with: /Documentable\sversion/
    #                   got: "version\r\n"
    1..1
    # You failed 1 test of 1
not ok 2 - version command
# Failed test 'version command'
# at t-test.t line 12
1..2
# You failed 1 test of 2
Execute "documentable --help" for more information.

一切似乎都很正常(显然测试失败)。问题是最后一行:

Execute "documentable --help" for more information.

该行由 CLI::MAIN() 添加,但不会在测试完成后执行。您甚至可以评论第一个子测试块,它仍然会出现。这导致使用 prove6 -l 的测试执行失败。知道发生了什么吗?

use CLI; 更改为 use CLI {}

问题

假设找到 CLI 包,运行 这个:

use CLI;

将显示:

Execute "documentable --help" for more information.

Unexpected output

以上显然不是您 想要的 ,但是您的测试代码不会改变 CLIused 的方式。因此不需要的消息应该是 expected 因为它是 MAIN 功能,它应该按预期工作。[1]

一个解决方案

您的问题归结为:

How do I use a package with exported MAINs while suppressing the automatic running of those MAINs?

一个简单的解决方案是不导入 MAIN(或者 &MAIN[2]。)

一种方法是将 use CLI; 替换为 use CLI {}

一个use CLI;语句等同于use CLI :DEFAULT;。 (:DEFAULT tag 拾取所有带有 is export 而没有不同标签的东西。)

如果你写 use CLI {} 而不是 没有 符号将被导入而不是 CLI 本身,它将被绑定到 [=14] 的符号=] 导出 在他们的包限定形式 .

这样您的 手动 测试 MAIN (指定 -- CLI::MAIN)将继续工作,但是自动调用它会被抑制。

脚注

[1] 如果文档没有说清楚:

  • CLI 包中 our proto MAIN 声明上的 is export exports a &MAIN[2] symbol;

  • use 语句 &MAIN 符号导入 t/01-test.t 的词法范围;

  • 命令 raku ... t/01-test.t 不带参数调用 t/01-test.tprove6 -l ... 也是如此(假设没有将 lib 之外的其他参数传递给主线)。因此调用零参数 &MAIN 调用;

  • 零参数调用解析为零参数 multi MAIN() { note 'Execute ... information'; } 声明。所以你看到了它的信息。

[2]MAIN 这样的子声明声明了一个符号 &MAIN。 (并且像 MAIN blah blah 这样的子 调用 调用与 &MAIN 关联的例程。)