8

I am writing a new Perl 6 project for work, and would like to be able to test whether all parts can be used correctly. For this, I'm using the use-ok subroutine from the Test module. I'm trying to easily test all module files using the following code:

"META6.json".IO.slurp.&from-json<provides>
.grep(*.value.starts-with("lib")).Hash.keys
.map({ use-ok $_ })

My issue here is that there are a few files that contain a definition for a MAIN subroutine. From the output I see when running prove -e 'perl6 -Ilib' t, it looks like one of the files is having their MAIN executed, and then the testing stops.

I want to test whether these files can be used correctly, without actually running the MAIN subs that are defined within them. How would I do this?

Tyil
  • 1,797
  • 9
  • 14
  • 1
    [tio](https://tio.run/##hdCxasMwEAbgXU9xiFDZwb7RQ1wKDrQ0Q2oo2YtMlMaJXQmdlDYYP7sru01Dpm6/frjvDhllm2wYPCnYKHI5G1NTVyBQ5IyR8daBCMVOazRtJhIQ2luYzZ/KEmoC9WW0dTmQr2BdrF6gA5Jn4FMOQxz6AF2dStpbZ1m8/uuEoRtn/bgpMjyQ/hAJEx1wY/Wp3irisICOAfCfi8fnJSa/9WQt/iLrJ5jxq8lxVSI13hq821ndpmN5f1nxwPDdKhPN8SQbr5CctI7Sz9rtoxHlcYzPkvZ4VGdi2EoTdRB@NdVHmL1BHw/DNw) seems to not run MAINs. [code for `use-ok`](https://github.com/rakudo/rakudo/blob/5ec2c96ec2df99701d755bb3bb99e8b2076ce616/lib/Test.pm6#L510) does `EVAL ( "use $code" );`. https://stackoverflow.com/questions/40778852/should-perl-6-run-main-if-the-file-is-required – raiph Oct 09 '18 at 13:33
  • Which module is running MAIN? – Christopher Bottoms Oct 11 '18 at 13:20
  • None of them _call_ `MAIN`, there's three files that _define_ a `MAIN`, and export it. During testing, when a module defining a `MAIN` is being tested with `use-ok`, the `MAIN` gets run and testing stops. This is my issue, I don't want `MAIN` to be ran when I'm using `use-ok`. – Tyil Oct 11 '18 at 19:58
  • @ChristopherBottoms: a new page https://docs.perl6.org/language/create-cli might explain it a bit. – Elizabeth Mattijsen Oct 15 '18 at 22:10

1 Answers1

5

The MAIN of a file is only executed if it is in the top level of the mainline of a program. So:

sub MAIN() is export { }     # this will be executed when the mainline executes

However, if you move the MAIN sub out of the toplevel, it will not get executed. But you can still export it.

{
    sub MAIN() is export { } # will *not* execute
}

Sorry for it taking so long to answer: it took a while for me to figure what the question was :-)

Elizabeth Mattijsen
  • 25,654
  • 3
  • 75
  • 105