brian d foy
brian d foy

Reputation: 132832

Specifying a Perl 6 class in a variable

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).

Upvotes: 9

Views: 283

Answers (1)

Jarrod Funnell
Jarrod Funnell

Reputation: 721

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/

Upvotes: 7

Related Questions