[英]How can I have a "private" Erlang module?
我更喜歡使用長度少於 1000 行的文件,因此我正在考慮將一些 Erlang 模塊分解成更小的部分。
有沒有辦法在不擴展我圖書館的公共 API 的情況下做到這一點?
我的意思是,只要有模塊,任何用戶都可以執行module:func_exported_from_the_module
。 據我所知,真正讓某些東西成為私有的唯一方法是不從任何模塊中導出它(即使那樣也可以戳洞)。
因此,如果在技術上沒有辦法完成我正在尋找的東西,是否有約定? 例如,Python類中沒有私有方法,但約定是在_my_private_method
中使用前導_
來標記為私有。
我承認答案可能是“不,你必須有 4K LOC 文件。”
最接近約定的是使用 edoc 標記,如@private
和@hidden
。
從文檔:
@hidden
標記 function,這樣它就不會出現在文檔中(即使生成了“私有”文檔)。 用於調試/測試功能等。內容可作為注釋; 它被 EDoc 忽略。
@private
將 function 標記為私有(即,不是公共接口的一部分),這樣它就不會出現在正常的文檔中。 (如果生成“私有”文檔,則將包含 function。)僅對導出函數有用,例如 spawn 的入口點。 (非導出函數始終是“私有的”。)內容可以用作注釋; 它被 EDoc 忽略。
請注意,這個答案開始於對@legoscia 的回答的評論
目前不支持不同方法的不同可見性。
當前的約定,如果你想那樣稱呼它,是有一個(或幾個)'facade' my_lib.erl
模塊導出你的庫/應用程序的公共 API。 調用庫的任何內部模塊都是在玩火,應該避免(調用它們需要您自擔風險)。
BEAM VM 中有一些非常好的功能依賴於能夠從任何模塊調用導出的函數,例如
Module:
的)重定向到最新版本,並將內部調用重定向到當前版本。 這就是為什么您可能會在長時間運行的服務器中看到一些?MODULE:
調用,以便能夠升級代碼您可能會爭辯說,這些點可用於更細粒度的面向 BEAM 的可見性級別,這是真的。 但我認為它不會解決外觀模塊無法解決的任何問題,並且會使 VM/代碼的其他部分變得非常復雜。
獎金
類似的情況適用於記錄和不透明類型,記錄僅在編譯時存在,而不透明類型僅在透析器時存在。 沒有什么能阻止你在任何地方訪問它們的內部結構,但如果你這樣 go ,你只會發現問題:
{record_name,...} =
breakopaque_adt()
的庫,您知道它是一個列表並像這樣使用。 庫升級為包含列表的大小,所以現在opaque_adt()
是一個tuple()
並且隨之而來的是混亂 只有那些在-export
屬性中指定的函數對其他模塊可見,即“公共”函數。 所有其他功能都是私有的。 如果您只指定了-compile(export_all)
,那么模塊中的所有函數在外部都是可見的。 不建議使用-compile(export_all)
。
我不知道 Erlang 有任何現有約定,但為什么不采用 Python 約定? 假設“庫私有”函數以下划線為前綴。 你需要用單引號引用 function 名稱才能工作:
-module(bar).
-export(['_my_private_function'/0]).
'_my_private_function'() ->
foo.
然后你可以稱它為:
> bar:'_my_private_function'().
foo
對我來說,這清楚地表明我不應該調用 function,除非我知道自己在做什么。 (甚至可能不會)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.