Should Perl 6 run MAIN if a file is needed?

Here is a small Perl 6 program that declares a MAIN routine. I should only see the output if I run the program directly:

$ cat main.pm6 sub MAIN { say "Called as a program!" } 

And I see the output when I run the program directly:

 $ perl6 main.pm6 Called as a program! 

If I load it as a module, I do not see the output:

 $ perl6 -I. -Mmain -e "say 'Hey'" Hey 

The same thing, if I use inside the program, I do not see the way out:

 $ perl6 -I. -e 'use main' 

But if I use require , I get the output:

 $ perl6 -I. -e 'require <main.pm6>' Called as a program! 

Synopsis 06 literally says that the compilation unit was directly called, and not required. Is there anything else because require works at runtime (although S06 doesn't rule this out)?

I get the same behavior with Rakudo Star 2016.07 and 2016.10.

+5
source share
2 answers

First, let's see how require should behave:

In accordance with (non-automatic) design documents ,

Alternatively, you can specify a file name directly, which installs a package that is actually anonymous for the current lexical field, and can be accessed only for any global names that the module installs:

and

Only names explicitly imported can be imported. To protect the harmfulness of the lexical panel, it cannot be changed to require .

In conjunction with S06

This call is made if and only if:

a) the compilation unit was directly called, and not required by another compilation unit [...]

As I understand it, you should not run sub MAIN that is not explicitly imported into the lexical area of ​​mainline.

Unfortunately, the user documentation is quiet in case of importing the runtime via the file name and a quick look at the (authoritarian) test suite (in particular S11-modules / require.t ) do not give an answer, although I may have missed it.

Now let's see how Rakudo behaves:

As expected, import runtime through a static or dynamic module name

 require main; 

or

 require ::('main'); 

will not start MAIN unless it is declared as is export and explicitly imported, i.e.

 require main <&MAIN>; 

and

 require ::('main') <&MAIN>; 

respectively.

Import via file name however

 require 'main.pm6'; 

will start MAIN immediately.

In fact, if you do the right import through

 require 'main.pm6' <&MAIN>; 

sub will be executed twice: once when loading the compilation module and the second time when the runtime does its job, scanning and launching any MAIN sub in the mainline area.

Rakudo seems to refer to require with a file name argument more or less similar to EVALFILE , and executes its main line, including any sub MAIN it encounters.

This is not what I would expect and maybe just a mistake.

+2
source

Synopsis documents are not a source of truth and are usually out of date in most places.

The way you use / require can also change the loading behavior of a module. -M does not use the use path "use xxx", and using a file name instead of a module name also changes the situation. Please note that the zef 'use' -s module is with MAIN and has the output https://github.com/ugexe/zef/blob/master/bin/zef

-1
source

Source: https://habr.com/ru/post/1260256/


All Articles