检查可选模块可用性的最佳方法

Fer*_*ata 5 module raku

在我正在编写的模块中,只有一种方法需要附加模块,因此我希望通过不在dependsMETA6.json 文件的一部分中列出该模块来使该模块成为可选。如果可选模块不可用,该方法将返回一个 Failure 对象。
我知道我可以做这样的事情:

if (try require Optional::Module) !=== Nil {
  # go on
} else {
  # fail
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来做到这一点?

Fer*_*ata 5

我要感谢所有回答或评论这个问题的人。
我对我提出的解决方案和我的问题的评论中给出的两个解决方案进行了基准测试:

my $pre = now;
for ^10000 {
  $*REPO.repo-chain.map(*.?candidates('Available::Module').Slip).grep(*.defined);
  $*REPO.repo-chain.map(*.?candidates('Unavailable::Module').Slip).grep(*.defined);
}
say now - $pre; # 13.223087

$pre = now;
for ^10000 {
  $*REPO.resolve(CompUnit::DependencySpecification.new(:short-name("Available::Module")));
  $*REPO.resolve(CompUnit::DependencySpecification.new(:short-name("Unavailable::Module")));
}
say now - $pre; # 3.105257

$pre = now;
for ^10000 {
  (try require Available::Module) !=== Nil;
  (try require Unavailable::Module) !=== Nil;
}
say now - $pre; # 4.963793
Run Code Online (Sandbox Code Playgroud)

更改模块名称以匹配系统上可用的模块名称和不可用的模块名称。
评论在我的电脑上以秒为单位显示结果。

  • 不要调用`$*REPO.installed`,因为只有某些类型的存储库才有`.installed`方法,并且您通常对*任何*存储库可以提供给定模块(而不仅仅是当前/头存储库)感兴趣。调用例如 `$*REPO.repo-chain.map(*.?installed)` 会更合适,但这不适用于 CURFS 提供的模块(`-I.`、`-Ilib` 等) ) (2认同)
  • `.resolve` `.load` 和 `.need` 值得注意,因为它将迭代整个存储库链,而像 `.candidates` 和 `.installed` 这样的所有其他方法都会给出它们所调用的特定存储库的结果(因此使用 `$*REPO.repo-chain.map(*.?installed.Slip)`) (2认同)