> On 11 Jul 2021, at 01:11, Joseph Brenner <doom...@gmail.com> wrote: > > I want my test files to be able to find the modules they're testing > just using their relative locations, given the usual layout of "lib" > and "t" locations in parallel inside the project directory. > > I find that while this works: > > use lib $*PROGRAM.parent.add('../lib'); > > This doesn't work: > > my $lib_loc = $*PROGRAM.parent.add('../lib'); > use lib "$lib_loc"; > > I get a compile time error > > Use of uninitialized value $lib_loc of type Any in string context. > ... > Repository specification can not be an empty string. Did you mean > 'use lib "."' ?
"use lib" is a compile time statement. "my $lib_loc = ..." is a runtime statement, with a compile time component for the definition. So what happens is that when the "use lib" is executed (at compile time), the $lib_loc variable *is* known, but it hasn't been initialized yet. Which is basically what the error message says :-) This can be easily fixed in Raku: the BEGIN statement can also be used as a prefix: BEGIN my $lib_loc = $*PROGRAM.parent.add('../lib'); use lib "$lib_loc"; One note: I'm a bit surprised of the mixture of OS dependent (../) and OS independent (.parent) directory walking. I guess you meant: $*PROGRAM.parent.parent.add("lib") ? If so, you could shorten this with the "sibling" method to: $*PROGRAM.parent.sibling("lib") > I thought that this would fix the problem, but I see the same > compile time error with it: > > BEGIN { > my $lib_loc = $*PROGRAM.parent.add('../lib'); > use lib "$lib_loc"; > } Inside the BEGIN block, it's just the same: the variable is defined, but not initialized yet when the "use lib" is executed at compile time *inside* the BEGIN block. Yes, it's compile times all the way down :-) > Does that make sense to anyone? It feels like a bug to me. This is not a bug. It's a misunderstanding of the phases through which a program goes when it is being compiled and run. This is not different from Perl, BTW. The only thing different from Perl (which is a very nice improvement, I'd say) is that you can use BEGIN as a prefix, so that it shares its scope with its surrounding scope. This allows you to define *and* initialize a variable at compile time and have it exist in the surrounding scope. Liz