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:
requirenow imports symbols lexically. If yourequireinside a block, the symbols won't be available outside of it.- Compile-time
requireinstalls a placeholderpackagesymbol 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
