When I do use Foo:ver<1.0>;
it loads version 1.0 of module Foo
. But what happens when I do use Foo;
?
TL;DR: When given no specific version a default Raku install will load the latest version from the first CompUnit::Repository
it encounters that matches any version of that module (and not neccesarily the highest version out of all CompUnit::Repository
).
It is possible to create and load a non-core CompUnit::Repository
that itself would only load random versions of a module unless otherwise specified. This answer does not apply to these and will focus on how the various core CompUnit::Repository
behave and is specced.
The first thing that determines what module will be loaded is which CompUnit::Repository
matches the requested identity first. The default repository chain will look something like this:
# EXAMPLE 1
$ raku -e '.say for $*REPO.repo-chain'
inst#/home/ugexe/.raku
inst#/home/ugexe/raku/install/share/perl6/site
inst#/home/ugexe/raku/install/share/perl6/vendor
inst#/home/ugexe/raku/install/share/perl6
The inst#
prefix tells us this is a CompUnit::Repository::Installation
. This is relevant because such a repo can contain multiple distributions -- including multiple versions of the same distribution -- which is not true of the single-distribution CompUnit::Repository::FileSystem
used for -I.
or -Ilib
(which are really -Ifile#/home/ugexe/repos/Foo
and -Ifile#/home/ugexe/repos/Foo/lib
).
# EXAMPLE 2
$ raku -I. -e '.say for $*REPO.repo-chain'
file#/home/ugexe/repos/Foo
inst#/home/ugexe/.raku
inst#/home/ugexe/raku/install/share/perl6/site
inst#/home/ugexe/raku/install/share/perl6/vendor
inst#/home/ugexe/raku/install/share/perl6
Lets assume the following:
file#/home/ugexe/repos/Foo
contains Foo:ver<0.5>
inst#/home/ugexe/.raku
contains Foo:ver<0.1>
and Foo:ver<1.0>
inst#/home/ugexe/.raku
contains Foo:ver<2.0>
and Foo:ver<0.1>
use Foo;
will load:
EXAMPLE 1 - Foo:ver<1.0>
from inst#/home/ugexe/.raku
EXAMPLE 2 - Foo:ver<0.5>
from file#/home/ugexe/repos/Foo
Even though the highest version out of all the repositories is Foo:ver<2.0>
the first repository in the chain that matches any version of Foo (i.e. use Foo
) wins, so Foo:ver<2.0>
is never chosen. You might guess this makes "highest version" the second thing that determines which version of a module gets loaded, but its really the 4th! However I've mentioned it here because for typical usage this is sufficient enough.
The 2nd thing that determines which version of a module get loaded is the api
field. This essentially is another version field that, when combined with the version itself, gives a basic way of pinning major versions.
Lets assume the following:
file#/home/ugexe/repos/Foo
contains Foo:api<0>:ver<0.5>
inst#/home/ugexe/.raku
contains Foo:api<1>:ver<0.1>
and Foo:api<0>:ver<1.0>
use Foo;
will load:
EXAMPLE 1 - Foo:api<1>:ver<0.1>
from inst#/home/ugexe/.raku
EXAMPLE 2 - Foo:api<0>:ver<0.5>
from file#/home/ugexe/repos/Foo
Even though in EXAMPLE 1 the highest version is Foo:api<0>:ver<1.0>
, the highest api version is Foo:api<1>:ver<0.1>
and thus is chosen.
The 3rd thing that determines which version of a module gets loaded is the auth
field. Unlike api
and ver
it does not imply any sorting. And also unlike api
and ver
field you probably shouldn't be using it in your e.g. use Foo
-- it is policy focused and will serve to be a power-tool/escape hatch most developers should hopefully never have to worry about (ab)using.
Lets assume the following:
file#/home/ugexe/repos/Foo
contains Foo:auth<github:ugexe>:ver<0.5>
inst#/home/ugexe/.raku
contains Foo:ver<0.1>
and Foo:auth<github:ugexe>:ver<1.0>
use Foo;
will load:
EXAMPLE 1 - Foo:auth<github:ugexe>:ver<1.0>
from inst#/home/ugexe/.raku
EXAMPLE 2 - Foo:auth<github:ugexe>:ver<0.5>
from file#/home/ugexe/repos/Foo
In both examples use Foo;
is the same as use Foo:auth(*):ver(*)
, so even though one of the repo assumptions contains a module with no auth
this does not mean it is an exact match for use Foo;
. Instead the :auth(*)
includes any auth
value as a match (effectively meaning auth
is ignored altogether).
For more examples the spec tests are a good source