Perl6如何决定加载哪个版本的模块?

问题描述 投票:8回答:1

当我做use Foo:ver<1.0>;它加载模块Foo 1.0版。但是当我做use Foo;时会发生什么?

module package versioning perl6 api-versioning
1个回答
10
投票

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。这是相关的,因为这样的回购可以包含多个分布 - 包括相同分布的多个版本 - 对于用于CompUnit::Repository::FileSystem-I.(实际上是-Ilib-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字段。与apiver不同,它并不意味着任何排序。而且,与apiver字段不同,您可能不应该在您的网站中使用它。 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)。


更多例子,spec tests是一个很好的来源

© www.soinside.com 2019 - 2024. All rights reserved.