First, let's take a look at how require
is supposed to behave:
According to the (non-authorative) design documents,
Alternately, a filename may be mentioned directly, which installs a package that is effectively anonymous to the current lexical scope, and may only be accessed by whatever global names the module installs:
and
Only explicitly mentioned names may be so imported. In order to protect the run-time sanctity of the lexical pad, it may not be modified by require
.
In combination with S06's
This call is performed if and only if:
a) the compilation unit was directly invoked rather than by being required by another compilation unit [...]
it is my understanding that a sub MAIN
not explicitly imported into the mainline lexical scope should not be run.
Sadly, the user documentation is quiet on the case of runtime importation via file name, and a quick glance at the (authorative) test suite (in particular S11-modules/require.t) did not yield an answer either, though I just might have missed it.
Now, let's take a look at how Rakudo behaves:
As expected, runtime importation via static or dynamic module name
require main;
or
require ::('main');
will not run MAIN
unless it is both declared is export
and explicitly imported, ie
require main <&MAIN>;
and
require ::('main') <&MAIN>;
respectively.
Importation via file name however
require 'main.rakumod';
will immediately run MAIN
.
In fact, if you do a proper import via
require 'main.rakumod' <&MAIN>;
the sub will be executed twice: Once when loading the compilation unit, and a second time when the runtime does its job looking and running any MAIN
sub in the mainline scope.
Rakudo apparently treats a require
with file name argument more or less like EVALFILE
and executes its mainline, including any sub MAIN
it encounters.
That's not what I would have expected and possibly just a bug.
require ::('main')
– Hierolatry