检查可选模块可用性的最佳方法
在我正在编写的模块中,只有一种方法需要附加模块,因此我希望通过不在dependsMETA6.json 文件的一部分中列出该模块来使该模块成为可选。如果可选模块不可用,该方法将返回一个 Failure 对象。
我知道我可以做这样的事情:
if (try require Optional::Module) !=== Nil {
# go on
} else {
# fail
}
有没有更好的方法来做到这一点?
回答
我要感谢所有回答或评论这个问题的人。
我对我提出的解决方案和我的问题的评论中给出的两个解决方案进行了基准测试:
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
更改模块名称以匹配系统上可用的模块名称和不可用的模块名称。
评论在我的电脑上以秒为单位显示结果。
- Don't call `$*REPO.installed` because only certain types of repos even have a `.installed` method, and you are generally interested if *any* repo can provide the given module (not just the current/head repo). It would be more appropriate to call e.g. `$*REPO.repo-chain.map(*.?installed)` but that wouldn't work with modules provided by a CURFS (`-I.`, `-Ilib`, etc)
- `.resolve` `.load` and `.need` are notable because it will iterate over the entire repo chain, whereas all other methods like `.candidates` and `.installed` give results for the specific repo they are called on (hence using `$*REPO.repo-chain.map(*.?installed.Slip)`)