I have a bunch of Perl 6 tests that start off with some basic tests where I put the class name to test in a variable the use that variable throughout the test:
my $package = 'Some::Class';
use-ok $package;
my $class = ::($package);
can-ok $class, 'new';
I hadn't paid attention to this for a bit, but it no longer works because classes are lexically loaded now:
No such symbol 'Some::Class'
It's not a hard fix. Load the module without use-ok
and in the scope where I want ::($package)
:
use Some::Class;
...
The other solutions (discounting an ugly EVAL
perhaps) have the issue I'm trying to avoid.
But, I don't particularly like that since the name shows up twice in the file. I've particularly liked my formerly-working idiom that I carried over from Perl 5. If I wanted to change a class name, it only showed up once in the file. I could easily generate boilerplate tests (although, it's not that much harder for the fix).
Is there a way I can get back to the ideal I wanted? (Although I figure lexical loading in the next version will get in the way again).
To sum up the problem: You want to load modules using a symbol instead of hardcoding it. Using a constant should do this for you:
constant some-module = 'Some::Module';
use ::(some-module);
You can also load the module at runtime using require
, which would allow runtime computed values:
my $some-module = 'Some::Module';
require ::($some-module);
::($some-module).foo
It would make sense to do this after trying a use-ok
.
For extra credit, you may find the techniques in this article useful. http://rakudo.org/2017/03/18/lexical-require-upgrade-info/
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With