【发布时间】:2021-06-13 08:17:12
【问题描述】:
我如何构建 Raku 代码,以便某些符号在我正在编写的库中在中是公开的,但对库的用户不公开? (我说“库”是为了避免术语“分发”和“模块”,文档有时会以重叠的方式使用它们。但如果我应该使用更精确的术语,请告诉我。)
我了解如何在单个文件中控制隐私。例如,我可能有一个文件Foo.rakumod,其内容如下:
unit module Foo;
sub private($priv) { #`[do internal stuff] }
our sub public($input) is export { #`[ code that calls &private ] }
使用此设置,&public 是我图书馆公共 API 的一部分,但 &private 不是 - 我可以在 Foo 中调用它,但我的用户不能。
如果&private 变得足够大以至于我想将其拆分到自己的文件中,我该如何保持这种分离?如果我将&private 移动到Bar.rakumod,那么我需要从Bar 模块给它our(即包)范围和export,以便能够从@use 它987654336@。但是这样做与我从Foo 导出&public 的方式相同,将导致我的库的用户能够use Foo 并调用&private——这正是我试图避免的结果。如何维护&private的隐私?
(我通过在 META6.json 文件中将 Foo 列为我的 distribution provides 的模块来研究强制隐私。但从文档中,我的理解是 provides 控制像 zef 安装的模块包管理器默认但实际上并不控制代码的隐私。对吗?)
[编辑:我得到的前几个回复让我怀疑我是否遇到了XY problem。我以为我在问“简单的事情应该是简单的”类别中的一些事情。我是从 Rust 背景来解决 API 边界的问题,common practice 是在 crate 中公开模块(或仅对它们的父模块)——这就是我问的 X。但如果有更好/不同的方式在 Raku 中强制执行 API 边界,我也会对该解决方案感兴趣(因为这是我真正关心的 Y)]
【问题讨论】:
-
我不相信你可以。要做的一件事可能是(a)将它们标记为
is implementation-detail(这表明这里是龙)并且(b)仅通过导出提供带有包密钥的子,例如use Foo::Secret :I-hereby-understand-that-foo-secret-is-designed-for-internal-use-only-and-agree-to-in-hold-the-module-author-harmless-for-any-and-all-damages-thereby-caused-in-sæcula-sæculorum,或者类似的巧妙写法(你毕竟是律师) -
另一种选择可能是将
EVAL从资源文件转换为my范围值,但我在将代码块存储在预编译文件中时遇到了问题,因此您可能必须在运行时完成,失去你无疑想要的好处(但也许 jnhtn 的新调度东西会产生修复它的副作用)
标签: module private encapsulation raku rakudo