Module 我怎样才能有一个;“私人”;Erlang模块?
我更喜欢处理长度小于1000行的文件,因此我考虑将一些Erlang模块分解成更小的部分 有没有一种方法可以在不扩展我的库的公共API的情况下实现这一点 我的意思是,任何时候有一个模块,任何用户都可以做Module 我怎样才能有一个;“私人”;Erlang模块?,module,erlang,Module,Erlang,我更喜欢处理长度小于1000行的文件,因此我考虑将一些Erlang模块分解成更小的部分 有没有一种方法可以在不扩展我的库的公共API的情况下实现这一点 我的意思是,任何时候有一个模块,任何用户都可以做module:func\u exported\u来自\u模块。据我所知,让某些东西真正成为私有的唯一方法是不从任何模块导出它(甚至可以戳出漏洞) 所以,如果从技术上讲,没有办法实现我所追求的目标,那么是否有一个惯例? 例如,Python类中没有私有方法,但惯例是在\u my\u private\u方
module:func\u exported\u来自\u模块
。据我所知,让某些东西真正成为私有的唯一方法是不从任何模块导出它(甚至可以戳出漏洞)
所以,如果从技术上讲,没有办法实现我所追求的目标,那么是否有一个惯例?
例如,Python类中没有私有方法,但惯例是在\u my\u private\u方法
中使用前导的\u
将其标记为私有
我同意答案可能是“不,您必须有4K LOC文件。”只有在
-export
属性中指定的功能对其他模块可见,即“公共”功能。所有其他功能都是私有的。如果只指定了-compile(export_all)
,则模块中的所有函数在外部可见。不建议使用-compile(export_all)
最接近约定的是使用edoc标记,如@private
和@hidden
发件人:
@隐藏
标记该函数,使其不会出现在
文档(即使生成了“私有”文档)。有用的
对于调试/测试功能等,内容可用作注释;
它被EDoc忽略了
@private
将功能标记为私有(即,不是公共的一部分
接口),使其不会出现在正常文档中。
(如果生成了“专用”文档,则该函数将
包括。)仅对导出的函数有用,例如
产卵。(非导出函数始终是“私有的”。)内容可以
用作评论;它被EDoc忽略了
我不知道Erlang有任何现有的约定,但是为什么不采用Python约定呢?假设“库私有”函数的前缀是下划线。要使函数名正常工作,您需要使用单引号引用函数名:
-module(bar).
-export(['_my_private_function'/0]).
'_my_private_function'() ->
foo.
然后,您可以将其称为:
> bar:'_my_private_function'().
foo
对我来说,这清楚地表明,除非我知道自己在做什么,否则我不应该调用该函数。(甚至可能不会)请注意,这个答案最初是对@Legossia答案的评论
目前不支持不同方法的不同可见性
如果您想这样称呼它,当前的约定是拥有一个(或多个)导出库/应用程序的公共API的“facade”my_lib.erl
模块。调用库的任何内部模块都是在玩火,应该避免(调用它们的风险由您自己承担)
BEAM VM中有一些非常好的特性,它们依赖于能够从任何模块调用导出的函数,例如
模块的调用:
)重定向到最新版本,将内部调用重定向到当前版本。这就是为什么您可能会在长时间运行的服务器中看到一些?模块:
调用,以便能够升级代码- 在记录中插入一个新字段,突然,所有的
都中断了{record\u name,…}=
- 如果您使用的库返回一个
,那么您知道它是一个列表,并且可以这样使用。库被升级为包含列表的大小,因此现在不透明的adt()
是一个opaque\u adt()
,混乱随之而来tuple()
my_lib.erl
仅导出库的公共接口。调用库中的任何其他方法都是在玩火(但这些方法需要可以从任何其他回调、行为、代码重新加载的代码中访问…)@JoséM我认为您应该基于此评论创建一个答案,这是这里唯一正确的答案。