develooper Front page | perl.perl6.users | Postings from July 2021

Re: use lib and locations in a variable

Thread Previous | Thread Next
Elizabeth Mattijsen
July 11, 2021 08:39
Re: use lib and locations in a variable
Message ID:
> On 11 Jul 2021, at 01:11, Joseph Brenner <> 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:



If so, you could shorten this with the "sibling" method to:


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

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About