Ric*_*rth 8 module precompiled raku
如何找到已在本地安装的模块,以及我可以use在 Raku 程序中找到的模块?
假设我们有三个分布:Parent、Brother、Sister。父母'提供'Top.rakumod,而 Brother 和 Sister 分别提供 'Top::Son.rakumod' 和 'Top::Daughter.rakumod'。兄弟姐妹在他们的 META6.json 中有一个 'depends': 'Top'。
每个发行版都在它自己的 git 存储库中。每个都是由zef安装的。
假设 Top 被设置为一个带有接口方法的类,可能类似于: multi method on-starting { ... },每个子类都必须实现它,并且在运行时为调用者提供有关子类的信息。这样既Top::Brother和Top::Daughter实施on-starting。也可能Top::Aunt存在未在本地安装的发行版等。我们需要找到安装了哪些。
所以,现在我们运行一个 Top 实例(在 Parent 中定义)。它需要寻找匹配的已安装模块Top::*。开始的地方(我认为)是$*REPO,它是包含已安装模块的存储库的链接列表。$*REPO 还承担 CompUnit::Repository 角色,后者又具有“need”方法。
我不明白的是如何操作 $*REPO 来获取所有匹配的候选模块的列表Top::*,以及整个链表。
一旦我有了候选列表,我就可以使用^can它来检查它是否有一个on-starting方法,然后调用该方法。
如果这不是得到 Top 发现本地安装模块的结果的方法,我会很感激我刚刚提出的方案的一些替代方案。
CompUnit::Repository(CUR) 有一种candidates搜索发行版的方法,但它不允许按名称前缀搜索(因为它还进行快速查找,需要全名才能获取其 sha1 目录/查找)。对于CompUnit::Repository::FileSystem(CURFS),您可以调用.distribution以获取它提供的分布,对于CompUnit::Repository::Installation(CURI),您可以调用.installed以获取它提供的所有分布:
raku -e ' \
say $*REPO.repo-chain \
.grep(CompUnit::Repository::FileSystem | CompUnit::Repository::Installation) \
.map({ $_ ~~ CompUnit::Repository::FileSystem ?? $_.distribution !! $_.installed.Slip }) \
.grep(*.defined) \
;'
Run Code Online (Sandbox Code Playgroud)
如果您想匹配命名空间,则需要 grep 发行版名称或其模块名称:
my @matches = @distributions.grep({ $_.meta<provides>.keys.first({.starts-with("Top::")}) });
Run Code Online (Sandbox Code Playgroud)
这种处理方式可以在Pluggable模块中看到(如果您也想加载此类代码,我建议使用该模块)
当然,您明确只要求安装的模块,但忽略 CURFS 没有任何意义——作为应用程序开发人员,不应该关心模块的加载位置或方式。如果有人想使用-I ./foo而不是安装它,就没有充分的理由忽略它。如果您坚持这样做,那么如何更改上面的示例以适应应该是显而易见的。
一旦我有了候选者列表,我可以使用 ^can 检查它是否有启动方法,然后调用该方法。
除了检查元文件或获取各种文件的源代码之外,拥有候选者列表不允许您执行任何其他操作。至少你会首先加载你想要调用的任何模块.^can,并且其中将涉及几个步骤,分发对象不能直接用于加载(你从中提取全名)并使用它来加载它)——所以我再次建议使用Pluggable
| 归档时间: |
|
| 查看次数: |
89 次 |
| 最近记录: |