首页 > 解决方案 > 执行包函数的意外输出

问题描述

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

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

您可以在此处查看来源。问题是,如果你运行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\01-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. 知道发生了什么吗?

标签: raku

解决方案


更改use CLI;use CLI {}

问题

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

use CLI;

将显示:

Execute "documentable --help" for more information.

意外输出

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

一个办法

您的问题归结为:

如何在抑制这些 s 的自动运行的同时use使用导出的 s 包?MAINMAIN

一种简单的解决方案是不导入MAIN(或者更确切地说&MAIN[2]。)

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

一个use CLI;语句等价于use CLI :DEFAULT;。(:DEFAULT标签会选择上面有的所有东西,is export而没有一些不同的标签。)

如果您use CLI {}改为编写,则除了自身之外不会导入任何CLI符号,这将绑定到以其包限定形式CLI导出的符号。

这样你的手动测试MAIN(指定-- CLI::MAIN)将继续工作,但它的自动调用将被禁止。

脚注

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

  • is export中的声明our proto MAIN导出一个[ 2]符号CLI&MAIN

  • use语句将该符号导入词法范围;&MAINt/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。)


推荐阅读