执行包函数的意外输出
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
以上显然不是您 想要的 ,但是您的测试代码不会改变 CLI
包 use
d 的方式。因此不需要的消息应该是 expected 因为它是 MAIN
功能,它应该按预期工作。[1]
一个解决方案
您的问题归结为:
How do I use
a package with exported MAIN
s while suppressing the automatic running of those MAIN
s?
一个简单的解决方案是不导入 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.t
,prove6 -l ...
也是如此(假设没有将 lib 之外的其他参数传递给主线)。因此调用零参数 &MAIN
调用;
零参数调用解析为零参数 multi MAIN() { note 'Execute ... information'; }
声明。所以你看到了它的信息。
[2] 像 MAIN
这样的子声明声明了一个符号 &MAIN
。 (并且像 MAIN blah blah
这样的子 调用 调用与 &MAIN
关联的例程。)
我有以下目录结构(重现问题的简化版本):
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
以上显然不是您 想要的 ,但是您的测试代码不会改变 CLI
包 use
d 的方式。因此不需要的消息应该是 expected 因为它是 MAIN
功能,它应该按预期工作。[1]
一个解决方案
您的问题归结为:
How do I
use
a package with exportedMAIN
s while suppressing the automatic running of thoseMAIN
s?
一个简单的解决方案是不导入 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.t
,prove6 -l ...
也是如此(假设没有将 lib 之外的其他参数传递给主线)。因此调用零参数&MAIN
调用;零参数调用解析为零参数
multi MAIN() { note 'Execute ... information'; }
声明。所以你看到了它的信息。
[2] 像 MAIN
这样的子声明声明了一个符号 &MAIN
。 (并且像 MAIN blah blah
这样的子 调用 调用与 &MAIN
关联的例程。)