当我这样做时use Foo:ver<1.0>;
,它会加载 1.0 版的 module Foo
。但是当我这样做时会发生什么use Foo;
?
1 回答
TL;DR:当没有指定特定版本时,默认 Perl6 安装将从CompUnit::Repository
遇到的第一个版本开始加载与该模块的任何版本匹配的最新版本(并且不一定是所有版本中的最高版本CompUnit::Repository
)。
CompUnit::Repository
除非另有说明,否则可以创建和加载本身只会加载模块的随机版本的非核心。该答案不适用于这些,并将重点关注各种核心的CompUnit::Repository
行为方式和规格。
确定将加载哪个模块的第一件事是首先CompUnit::Repository
匹配请求的身份。默认存储库链将如下所示:
# EXAMPLE 1
$ perl6 -e '.say for $*REPO.repo-chain'
inst#/home/ugexe/.perl6
inst#/home/ugexe/perl6/install/share/perl6/site
inst#/home/ugexe/perl6/install/share/perl6/vendor
inst#/home/ugexe/perl6/install/share/perl6
inst#
前缀告诉我们这是一个CompUnit::Repository::Installation
. 这是相关的,因为这样的 repo 可以包含多个发行版——包括同一发行版的多个版本——这CompUnit::Repository::FileSystem
对于用于-I.
or的单个发行版-Ilib
(实际上是and -Ifile#/home/ugexe/repos/Foo
)是不正确的-Ifile#/home/ugexe/repos/Foo/lib
。
# EXAMPLE 2
$ perl6 -I. -e '.say for $*REPO.repo-chain'
file#/home/ugexe/repos/Foo
inst#/home/ugexe/.perl6
inst#/home/ugexe/perl6/install/share/perl6/site
inst#/home/ugexe/perl6/install/share/perl6/vendor
inst#/home/ugexe/perl6/install/share/perl6
让我们假设以下内容:
file#/home/ugexe/repos/Foo
包含Foo:ver<0.5>
inst#/home/ugexe/.perl6
包含Foo:ver<0.1>
和Foo:ver<1.0>
inst#/home/ugexe/.perl6
包含Foo:ver<2.0>
和Foo:ver<0.1>
use Foo;
将加载:
示例 1 -
Foo:ver<1.0>
从inst#/home/ugexe/.perl6
示例 2 -
Foo:ver<0.5>
从file#/home/ugexe/repos/Foo
即使所有存储库Foo:ver<2.0>
中的最高版本是链中与Foo 的任何版本(即use Foo
)匹配的第一个存储库,Foo:ver<2.0>
也不会被选中。您可能会猜到这使得“最高版本”成为决定加载模块版本的第二个因素,但它实际上是第 4 个!但是我在这里提到了它,因为对于典型的用法,这已经足够了。
确定加载哪个版本的模块的第二件事是api
字段。这本质上是另一个版本字段,当与版本本身结合时,它提供了一种固定主要版本的基本方法。
让我们假设以下内容:
file#/home/ugexe/repos/Foo
包含Foo:api<0>:ver<0.5>
inst#/home/ugexe/.perl6
包含Foo:api<1>:ver<0.1>
和Foo:api<0>:ver<1.0>
use Foo;
将加载:
示例 1 -
Foo:api<1>:ver<0.1>
从inst#/home/ugexe/.perl6
示例 2 -
Foo:api<0>:ver<0.5>
从file#/home/ugexe/repos/Foo
尽管在示例 1 中最高版本是Foo:api<0>:ver<1.0>
,但最高 api 版本是Foo:api<1>:ver<0.1>
,因此被选择。
确定加载哪个模块版本的第三件事是auth
字段。不同api
,ver
它并不意味着任何排序。并且与api
字段不同的是,ver
您可能不应该在您的示例中使用它use Foo
——它以政策为重点,并将成为大多数开发人员希望永远不必担心(ab)使用的电动工具/逃生舱。
让我们假设以下内容:
file#/home/ugexe/repos/Foo
包含Foo:auth<github:ugexe>:ver<0.5>
inst#/home/ugexe/.perl6
包含Foo:ver<0.1>
和Foo:auth<github:ugexe>:ver<1.0>
use Foo;
将加载:
示例 1 -
Foo:auth<github:ugexe>:ver<1.0>
从inst#/home/ugexe/.perl6
示例 2 -
Foo:auth<github:ugexe>:ver<0.5>
从file#/home/ugexe/repos/Foo
在这两个示例use Foo;
中都与 相同use Foo:auth(*):ver(*)
,因此即使其中一个 repo 假设包含一个没有的模块,auth
这并不意味着它与use Foo;
. 相反,它:auth(*)
包含任何auth
值作为匹配项(实际上auth
完全忽略了含义)。
有关更多示例,规范测试是一个很好的来源