What's Happening?
Rakudo Compiler release 2017.03 includes the final piece of lexical module loading work: lexical require
. This work was first announced in December, in http://rakudo.org/2016/12/17/lexical-module-loading/
There are two changes that may impact your code:
require
now imports symbols lexically. If yourequire
inside a block, the symbols won't be available outside of it.- Compile-time
require
installs a placeholderpackage
symbol that remains available even if required item was not found.
Upgrade Information
Lexical Symbols
WRONG:
# WRONG:
try { require Foo; 1 } and ::('Foo').new;
The require
above is inside a block and so its symbols won't be available
outside of it and the look up will fail.
CHANGE TO:
(try require Foo) !=== Nil and ::('Foo').new;
Now the require
installs the symbols into scope that's lexically accessible
to the ::('Foo')
look up.
Optional Loading
WRONG:
# WRONG:
try require Foo;
if ::('Foo') ~~ Failure {
say "Failed to load Foo!";
}
This construct installs a package
named Foo
, which would be replaced by the
loaded Foo
if it were found, but if it weren't, the package
will remain a
package
, not a Failure
, and so the above ~~
test will always be False
.
CHANGE TO:
# Use return value to test whether loading succeeded:
(try require Foo) === Nil and say "Failed to load Foo!";
# Or use a run-time symbol lookup with require, to avoid compile-time
# package installation:
try require ::('Foo');
if ::('Foo') ~~ Failure {
say "Failed to load Foo!";
}
In the first example above, we test the return value of try
isn't Nil
, since
on successful loading it will be a Foo
module, class, or package.
The second example uses a run-time symbol lookup in require
and so it never needs
to install the package
placeholder during the compile time. Therefore, the
::('Foo') ~~
test does work as intended.
Help and More Info
If you require help or more information, please join our chat channel #perl6 on irc.freenode.net