In Modules§
See primary documentation in context for require
require
loads a compunit and imports definite symbols at runtime.
say "loading MyModule"; require MyModule;
The compunit name can be in a runtime variable if you put it inside an indirect lookup.
my $name = 'MyModule'; require ::($name);
The symbols provided by the loaded module will not be imported into the current scope. You may use dynamic lookup or dynamic subsets to use them by providing the fully qualified name of a symbol, for instance:
require ::("Test"); my &mmk = ::("Test::EXPORT::DEFAULT::&ok"); mmk('oi‽'); # OUTPUT: «ok 1 - »
The FQN of ok
is Test::EXPORT::DEFAULT::&ok
. We are aliasing it to mmk
so that we can use that symbol provided by Test
in the current scope.
To import symbols you must define them at compile time. NOTE: require
is lexically scoped:
sub do-something { require MyModule <&something>; say ::('MyModule'); # MyModule symbol exists here something() # &something will be defined here } say ::('MyModule'); # This will NOT contain the MyModule symbol do-something(); # &something will not be defined here
If MyModule
doesn't export &something
then require
will fail.
A require
with compile-time symbol will install a placeholder package
that will be updated to the loaded module, class, or package. Note that the placeholder will be kept, even if require failed to load the module. This means that checking if a module loaded like this is wrong:
# *** WRONG: *** try require Foo; if ::('Foo') ~~ Failure { say "Failed to load Foo!"; } # *** WRONG: ***
As the compile-time installed package causes ::('Foo')
to never be a Failure
. The correct way is:
# Use return value to test whether loading succeeded: (try require Foo) === Nil and say "Failed to load Foo!"; # Or use a runtime symbol lookup with require, to avoid compile-time # package installation: try require ::('Foo'); if ::('Foo') ~~ Failure { say "Failed to load Foo!"; }
In the current (6.d) version of the language, require
d symbols are no longer transitively exposed, which means that you need to import symbols from the module they were originally declared, not from the module where they have been imported.