檢視原始碼 code (kernel v10.2)

Erlang 程式碼伺服器程序的介面。

此模組包含 Erlang *程式碼伺服器* 的介面,該伺服器負責將編譯後的程式碼載入到正在執行的 Erlang 執行時期系統中。

執行時期系統可以以*互動式*或*嵌入式*模式啟動。具體使用哪種模式取決於命令行標誌 -mode

% erl -mode embedded

模式如下:

  • 在*互動式*模式(預設)中,只有執行時期系統需要的模組會在系統啟動期間載入。其他程式碼會在首次被引用時動態載入。當呼叫特定模組中的函式,而該模組尚未載入時,程式碼伺服器會搜尋並嘗試載入該模組。

  • 在*嵌入式*模式中,模組不會自動載入。嘗試使用尚未載入的模組將會導致錯誤。當啟動腳本載入所有模組時(如 OTP 發行版中通常的做法),建議使用此模式。(程式碼仍然可以稍後透過明確指示程式碼伺服器來載入)。

為了防止意外重新載入影響 Erlang 執行時期系統的模組,目錄 kernelstdlibcompiler 被視為*黏性*。這表示如果使用者嘗試重新載入駐留在其中任何一個目錄中的模組,系統會發出警告並拒絕該請求。可以使用命令行標誌 -nostick 停用此功能。

程式碼路徑

在互動模式下,程式碼伺服器會維護一個*程式碼路徑*,其中包含一個目錄列表,當嘗試載入模組時,它會依序搜尋這些目錄。

最初,程式碼路徑由當前工作目錄和庫目錄 $OTPROOT/lib 下的所有 Erlang 目標程式碼目錄組成,其中 $OTPROOT 是 Erlang/OTP 的安裝目錄,即 code:root_dir()。目錄可以命名為 Name[-Vsn],預設情況下,程式碼伺服器會選擇具有相同 Name 的目錄中版本號最高的目錄。後綴 -Vsn 是可選的。如果 Name[-Vsn] 下存在 ebin 目錄,則此目錄會新增至程式碼路徑。

可以使用環境變數 ERL_LIBS(在作業系統中定義)來定義更多庫目錄,其處理方式與上述標準 OTP 庫目錄相同,但會忽略沒有 ebin 目錄的目錄。

在其他目錄中找到的所有應用程式目錄都會顯示在標準 OTP 應用程式之前,但 Kernel 和 STDLIB 應用程式除外,它們會放置在任何其他應用程式之前。換句話說,在任何其他庫目錄中找到的模組會覆蓋 OTP 中具有相同名稱的模組,但 Kernel 和 STDLIB 中的模組除外。

環境變數 ERL_LIBS(如果已定義)應包含一個以冒號分隔(對於類 Unix 系統)或以分號分隔(對於 Windows)的額外庫列表。

範例

在類 Unix 系統上,可以將 ERL_LIBS 設定為以下內容:

/usr/local/jungerl:/home/some_user/my_erlang_lib

$OTPROOTERL_LIBS 和啟動腳本指定的程式碼路徑預設會快取其清單("." 除外)。程式碼伺服器會查詢一次其目錄中的內容,並避免未來進行檔案系統遍歷。因此,在 Erlang VM 啟動後新增至此類目錄的模組將不會被選取。可以透過設定 -cache_boot_paths false 或呼叫 code:set_path(code:get_path()) 來停用此行為。

變更

對程式碼路徑中的目錄進行快取的支援是在 Erlang/OTP 26 中新增的。

命令行選項 -pa-pz 給定的目錄預設不會快取。許多操作程式碼路徑的函式都接受 cache atom 作為可選參數,以選擇性啟用快取。

從封存檔案載入程式碼

變更

對封存檔案的現有實驗性支援將在未來版本中變更。自 Erlang/OTP 27 起,函式 code:lib_dir/2-code_path_choice 標誌,以及使用 erl_prim_loader 從封存檔案讀取檔案已被棄用。

使用封存檔案的 escript 腳本應使用 escript:extract/2 從其封存讀取資料檔案,而不是使用 code:lib_dir/2erl_prim_loader

Erlang 封存檔案是副檔名為 .ezZIP 檔案。Erlang 封存檔案也可以封閉在 escript 檔案中,其副檔名是任意的。

Erlang 封存檔案可以包含整個 Erlang 應用程式或應用程式的一部分。封存檔案中的結構與應用程式的目錄結構相同。例如,如果您建立 mnesia-4.4.7 的封存檔,則該封存檔必須命名為 mnesia-4.4.7.ez,並且必須包含一個名為 mnesia-4.4.7 的頂層目錄。如果省略名稱的版本部分,則也必須在封存檔中省略。也就是說,mnesia.ez 封存檔必須包含一個 mnesia 頂層目錄。

應用程式的封存檔案可以像這樣建立:

zip:create("mnesia-4.4.7.ez",
	["mnesia-4.4.7"],
	[{cwd, code:lib_dir()},
	 {compress, all},
	 {uncompress,[".beam",".app"]}]).

封存檔中的任何檔案都可以壓縮,但是為了加快存取頻繁讀取的檔案,最好將 beamapp 檔案以未壓縮的形式儲存在封存檔中。

通常,應用程式的頂層目錄位於庫目錄 $OTPROOT/lib 中,或位於環境變數 ERL_LIBS 引用的目錄中。在啟動時,當計算初始程式碼路徑時,程式碼伺服器也會在這些目錄中尋找封存檔案,並可能會將封存檔中的 ebin 目錄新增到程式碼路徑。然後,程式碼路徑會包含看起來像 $OTPROOT/lib/mnesia.ez/mnesia/ebin$OTPROOT/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin 的目錄的路徑。

程式碼伺服器使用 ERTS 中的模組 erl_prim_loader(可能透過 erl_boot_server)來從封存檔讀取程式碼檔案。但是,其他應用程式也可以使用 erl_prim_loader 中的函式來從封存檔讀取檔案。例如,呼叫 erl_prim_loader:list_dir( "/otp/root/lib/mnesia-4.4.7.ez/mnesia-4.4.7/examples/bench)" 將會列出封存檔內目錄的內容。請參閱 erl_prim_loader

應用程式封存檔和常規應用程式目錄可以共存。當需要將應用程式的一部分作為常規檔案時,這很有用。一個典型的案例是 priv 目錄,它必須作為常規目錄駐留才能動態連結驅動程式並啟動埠程式。對於其他不需要此功能的應用程式,目錄 priv 可以駐留在封存檔中,並且可以透過 erl_prim_loader 讀取目錄 priv 下的檔案。

當目錄新增至程式碼路徑時,以及當整個程式碼路徑被(重新)設定時,程式碼伺服器會決定應用程式中的哪些子目錄要從封存檔讀取,哪些要作為常規檔案讀取。如果稍後新增或移除目錄,則如果未更新程式碼路徑(可能與之前的路徑相同,以觸發目錄解析更新),則檔案存取可能會失敗。

對於應用程式封存檔中第二層的每個目錄(ebinprivsrc 等),程式碼伺服器首先選擇常規目錄(如果存在),其次從封存檔選擇。函式 code:lib_dir/2 會傳回子目錄的路徑。例如,code:lib_dir(megaco, ebin) 可以傳回 /otp/root/lib/megaco-3.9.1.1.ez/megaco-3.9.1.1/ebin,而 code:lib_dir(megaco, priv) 可以傳回 /otp/root/lib/megaco-3.9.1.1/priv

escript 檔案包含封存檔時,對於 escript 的名稱沒有限制,對於可以儲存在嵌入式封存檔中的應用程式數量也沒有限制。單個 Beam 檔案也可以駐留在封存檔的頂層。在啟動時,嵌入式封存檔中的頂層目錄和嵌入式封存檔中的所有(第二層)ebin 目錄都會新增到程式碼路徑。請參閱 escript

escript 腳本從封存檔讀取資料檔案的未來防護方式是使用 escript:extract/2 函式。

當程式碼路徑中的目錄選擇為 strict 時(自 Erlang/OTP 27 起的預設值),最終在程式碼路徑中的目錄正是所聲明的目錄。這表示,例如,如果將目錄 $OTPROOT/lib/mnesia-4.4.7/ebin 明確新增到程式碼路徑中,則程式碼伺服器不會從 $OTPROOT/lib/mnesia-4.4.7.ez/mnesia-4.4.7/ebin 載入檔案。

此行為可以透過命令行標誌 -code_path_choice Choice 控制。如果將該標誌設定為 relaxed,則程式碼伺服器會改為根據實際檔案結構選擇適當的目錄。如果存在常規應用程式 ebin 目錄,則會選擇它。否則,如果存在,則會選擇封存檔中的目錄 ebin。如果它們都不存在,則會選擇原始目錄。

命令行標誌 -code_path_choice Choice 也會影響模組 init 解譯 boot script 的方式。boot script 中明確程式碼路徑的解譯可以是 strictrelaxed。當在不編輯 boot script 的情況下詳細說明從封存檔載入程式碼時,將該標誌設定為 relaxed 特別有用。預設值在 OTP 27 中已變更為 strict,並且該選項計劃在 OTP 28 中移除。請參閱 Erts 應用程式中的模組 init

目前程式碼和舊程式碼

系統中一個模組的程式碼可以存在兩種變體:*目前程式碼*和*舊程式碼*。當模組第一次載入到系統時,模組程式碼會變成*目前*,並且全域*匯出表*會使用對從模組匯出的所有函式的參考來更新。

當載入模組的新實例時,先前實例的程式碼會變成舊的,並且所有參照先前實例的匯出條目都會被移除。之後,新的實例會像第一次一樣被載入,並成為目前的實例。

模組的舊程式碼和目前程式碼都是有效的,甚至可以同時執行。不同之處在於舊程式碼中的匯出函數是不可用的。因此,無法對舊程式碼中的匯出函數進行全域呼叫,但由於其中仍有程序存在,舊程式碼仍然可以執行。

如果載入了模組的第三個實例,程式碼伺服器會移除(清除)舊程式碼,並且其中任何存在的程序都會被終止。然後,第三個實例會成為目前的實例,而先前目前的程式碼則會變成舊的。

關於舊程式碼和目前程式碼的更多資訊,以及如何使程序從舊程式碼切換到目前程式碼,請參閱Erlang 參考手冊中的「編譯和程式碼載入」章節。

原生涵蓋率支援

在使用 JIT 的執行時系統中,原生涵蓋率是一種輕量級的方式,可以找出哪些函數或程式碼行已被執行,或者每個函數或程式碼行已執行多少次。

變更

對原生涵蓋率的支援是在 Erlang/OTP 27 中加入的。

原生涵蓋率的工作方式是在載入時對程式碼進行檢測。當一個模組已針對原生涵蓋率收集進行檢測時,除非重新載入該模組,否則之後無法停用涵蓋率收集。但是,保持涵蓋率收集運行的開銷通常可以忽略不計,尤其對於僅追蹤哪些函數已執行的涵蓋率模式 function

如果執行時系統支援,Tools 應用程式中的 cover 工具會自動使用原生涵蓋率支援。

只有在 cover 不足夠時,才需要使用接下來描述的功能,例如:

  • 如果想要收集執行時系統啟動時運行的程式碼(模組 init 等)的涵蓋率資訊。cover 只能在 Erlang 系統啟動後使用,並且它會重新載入每個要分析的模組。

  • 如果需要以對測試系統的絕對最小干擾來收集涵蓋率資訊。cover 總是會計算每行程式碼被執行的次數(涵蓋率模式 line_counters),但是透過使用原生涵蓋率,可以使用較低開銷的涵蓋率模式,例如 function,它的開銷幾乎可以忽略不計。

使用原生涵蓋率的簡短摘要

如果要使用 lineline_counters 涵蓋率模式,則必須使用選項 line_coverage 編譯要測試的程式碼。

使用 set_coverage_mode(Mode) 為之後載入的所有程式碼設定涵蓋率模式,或者使用 erl 的選項 +JPcover 進行設定。

可選地,透過呼叫 reset_coverage(Module) 來重設要測試的所有模組的涵蓋率資訊。

執行要收集其涵蓋率資訊的程式碼。

透過呼叫 get_coverage(Level, Module) 讀取所有感興趣模組的計數器,其中 Levelfunctionline

其他原生涵蓋率 BIF

以下 BIF 有時很有用,例如,如果執行時系統不支援原生涵蓋率,可以優雅地失敗

引數型別和無效引數

模組和應用程式名稱是原子,而檔案和目錄名稱是字串。出於向後相容性的原因,某些函數接受字串和原子,但未來版本可能只允許已記載的引數。

如果將不正確的型別(例如,預期為原子卻傳入整數或元組)傳遞給此模組中的函數,通常會導致例外狀況。如果引數型別正確,但存在其他錯誤(例如,為 set_path/1 指定了不存在的目錄),則會傳回錯誤元組。

程式碼載入函數的錯誤原因

如果載入操作失敗,則載入程式碼的函數(例如 load_file/1)將傳回 {error,Reason}。以下是常見原因的描述。

  • badfile - 物件程式碼的格式不正確,或物件程式碼中的模組名稱不是預期的模組名稱。

  • nofile - 未找到具有物件程式碼的檔案。

  • not_purged - 因為已存在程式碼的舊版本,所以無法載入物件程式碼。

  • on_load_failure - 模組有一個 -on_load 函數,在呼叫時失敗。

  • sticky_directory - 物件程式碼位於黏性目錄中。

摘要

函數

Dir 加入到程式碼路徑的開頭。

遍歷 Dirs 並將每個 Dir 加入到程式碼路徑的開頭。

Dirs 中的目錄加入到程式碼路徑的結尾。

Dir 作為程式碼路徑中的最後一個目錄加入。

傳回所有可用模組的元組清單 {Module, Filename, Loaded}

傳回所有已載入模組的元組清單 {Module, Loaded}

嘗試以原子方式載入清單 Modules 中的所有模組。

在程式碼路徑中的所有目錄中搜尋具有相同名稱的模組名稱,並將報告寫入 stdout

清除程式碼路徑快取。

傳回編譯器程式庫目錄。

如果系統支援涵蓋率,則傳回 true,否則傳回 false

從程式碼路徑中刪除目錄。

從程式碼路徑中刪除多個目錄。

移除 Module 的目前程式碼,也就是說,Module 的目前程式碼會變成舊的。

嘗試以與 load_file/1 相同的方式載入模組,除非模組已經載入。

嘗試以與 load_file/1 相同的方式載入清單 Modules 中尚未載入的任何模組。

嘗試載入先前由 prepare_loading/1 準備的所有模組的程式碼。

傳回模組 Modulefunctionline 涵蓋率資料。

傳回由 erl 的選項 +JPcoverset_coverage_mode/1 設定的涵蓋率模式。

取得指定模組的涵蓋率模式。

如果可用,則傳回 ModuleEEP 48 風格文件。

傳回描述程式碼伺服器模式的原子:interactiveembedded

如果在程式碼路徑中找到,則傳回模組 Module 的物件程式碼。

傳回程式碼路徑。

檢查是否已載入 Module

如果 Module 是從黏性目錄載入的模組名稱(換句話說:嘗試重新載入該模組將會失敗),則傳回 true;如果 Module 不是已載入的模組或不是黏性的,則傳回 false

傳回程式庫目錄 $OTPROOT/lib,其中 $OTPROOT 是 Erlang/OTP 的根目錄。

傳回應用程式 Name程式庫目錄(頂層目錄)路徑,該應用程式位於 $OTPROOT/lib 下或以環境變數 ERL_LIBS 參照的目錄中。

傳回應用程式頂層目錄下的子目錄路徑。

等同於 load_file(Module),不同之處在於 Filename 是絕對或相對檔名。

從二進位資料載入物件程式碼。

嘗試使用程式碼路徑載入 Erlang 模組 Module

傳回目前已載入的所有模組的清單,其中 module_status/1 傳回 modified

詳細資訊請參閱 module_status/1all_loaded/0

傳回 Module 相對於磁碟上物件檔案的狀態。

返回對應於所使用 Erlang 機器的目標碼檔案副檔名。

準備載入列表 Modules 中的模組。

返回應用程式中 priv 目錄的路徑。

清除 Module 的程式碼,也就是移除標記為舊的程式碼。

將程式碼路徑中名為 .../Name[-Vsn][/ebin] 的舊目錄出現位置,取代為 Dir

重設模組 Module 的覆蓋率資訊。

返回 Erlang/OTP 的根目錄,也就是其安裝所在的目錄。

設定後續載入模組的覆蓋率模式,類似於 erl 的選項 +JPcover

將程式碼路徑設定為目錄列表 Path

清除 Module 的程式碼,也就是移除標記為舊的程式碼,但僅限於其中沒有持續執行的程序。

Dir 標記為黏性的。

取消標記為黏性的目錄。

在程式碼路徑中搜尋 Filename,這是一個任意類型的檔案。

如果模組尚未載入,此函式會在程式碼路徑中搜尋第一個包含 Module 目標碼的檔案,並返回絕對檔案名稱。

類型

此類型的連結

add_path_ret()

查看原始碼 (未匯出)
-type add_path_ret() :: true | {error, bad_directory}.
-type cache() :: cache | nocache.
-type coverage_mode() :: none | function | function_counters | line_coverage | line_counters.
-type load_error_rsn() :: badfile | nofile | not_purged | on_load_failure | sticky_directory.
-type load_ret() :: {error, What :: load_error_rsn()} | {module, Module :: module()}.
此類型的連結

loaded_filename()

查看原始碼 (未匯出)
-type loaded_filename() :: (Filename :: file:filename()) | loaded_ret_atoms().
此類型的連結

loaded_ret_atoms()

查看原始碼 (未匯出)
-type loaded_ret_atoms() :: cover_compiled | preloaded.
-type module_status() :: not_loaded | loaded | modified | removed.
-opaque prepared_code()

一個不透明的術語,保存預備好的程式碼。

此類型的連結

replace_path_ret()

查看原始碼 (未匯出)
-type replace_path_ret() :: true | {error, bad_directory | bad_name | {badarg, _}}.
此類型的連結

set_path_ret()

查看原始碼 (未匯出)
-type set_path_ret() :: true | {error, bad_directory}.

函式

-spec add_path(Dir) -> add_path_ret() when Dir :: file:filename().

等同於 add_pathz(Dir, nocache)

此函式的連結

add_path(Dir, Cache)

查看原始碼 (自 OTP 26.0 起)
-spec add_path(Dir, cache()) -> add_path_ret() when Dir :: file:filename().

等同於 add_pathz(Dir, Cache)

-spec add_patha(Dir) -> add_path_ret() when Dir :: file:filename().

等同於 add_patha(Dir, nocache)

此函式的連結

add_patha(Dir, Cache)

查看原始碼 (自 OTP 26.0 起)
-spec add_patha(Dir, cache()) -> add_path_ret() when Dir :: file:filename().

Dir 加入到程式碼路徑的開頭。

如果 Dir 存在,它會從程式碼路徑中的舊位置移除。

引數 Cache 控制是否應在第一次遍歷時快取目錄的內容。如果 Cachecache,目錄內容將被快取;如果 Cachenocache,則不會被快取。

如果成功,則返回 true,如果 Dir 不是目錄名稱,則返回 {error, bad_directory}

-spec add_paths(Dirs) -> ok when Dirs :: [Dir :: file:filename()].

等同於 add_pathsz(Dirs, nocache)

此函式的連結

add_paths(Dirs, Cache)

查看原始碼 (自 OTP 26.0 起)
-spec add_paths(Dirs, cache()) -> ok when Dirs :: [Dir :: file:filename()].

等同於 add_pathsz(Dirs, Cache)

-spec add_pathsa(Dirs) -> ok when Dirs :: [Dir :: file:filename()].

等同於 add_pathsa(Dirs, nocache)

此函式的連結

add_pathsa(Dirs, Cache)

查看原始碼 (自 OTP 26.0 起)
-spec add_pathsa(Dirs, cache()) -> ok when Dirs :: [Dir :: file:filename()].

遍歷 Dirs 並將每個 Dir 加入到程式碼路徑的開頭。

這表示 Dirs 的順序會在產生的程式碼路徑中反轉。例如,如果 Dirs[Dir1,Dir2],產生的路徑將會是 [Dir2,Dir1|OldCodePath]

如果程式碼路徑中已存在 Dir,它會從舊位置移除。

引數 Cache 控制是否應在第一次遍歷時快取目錄的內容。如果 Cachecache,目錄內容將被快取;如果 Cachenocache,則不會被快取。

無論每個單獨的 Dir 的有效性為何,皆一律返回 ok

-spec add_pathsz(Dirs) -> ok when Dirs :: [Dir :: file:filename()].

等同於 add_pathsz(Dirs, nocache)

此函式的連結

add_pathsz(Dirs, Cache)

查看原始碼 (自 OTP 26.0 起)
-spec add_pathsz(Dirs, cache()) -> ok when Dirs :: [Dir :: file:filename()].

Dirs 中的目錄加入到程式碼路徑的結尾。

路徑中已存在的目錄將不會被新增。

引數 Cache 控制是否應在第一次遍歷時快取目錄的內容。如果 Cachecache,目錄內容將被快取;如果 Cachenocache,則不會被快取。

無論每個單獨的 Dir 的有效性為何,皆一律返回 ok

-spec add_pathz(Dir) -> add_path_ret() when Dir :: file:filename().

等同於 add_pathz(Dir, nocache)

此函式的連結

add_pathz(Dir, Cache)

查看原始碼 (自 OTP 26.0 起)
-spec add_pathz(Dir, cache()) -> add_path_ret() when Dir :: file:filename().

Dir 作為程式碼路徑中的最後一個目錄加入。

如果路徑中已存在 Dir,則不會新增。

引數 Cache 控制是否應在第一次遍歷時快取目錄的內容。如果 Cachecache,目錄內容將被快取;如果 Cachenocache,則不會被快取。

如果成功,則返回 true,如果 Dir 不是目錄名稱,則返回 {error, bad_directory}

此函式的連結

all_available()

查看原始碼 (自 OTP 23.0 起)
-spec all_available() -> [{Module, Filename, Loaded}]
                       when Module :: string(), Filename :: loaded_filename(), Loaded :: boolean().

傳回所有可用模組的元組清單 {Module, Filename, Loaded}

如果模組已載入或在呼叫時會被載入,則視為可用。Filename 通常是絕對檔案名稱,如 is_loaded/1 所述。

-spec all_loaded() -> [{Module, Loaded}] when Module :: module(), Loaded :: loaded_filename().

傳回所有已載入模組的元組清單 {Module, Loaded}

Loaded 通常是絕對檔案名稱,如 is_loaded/1 所述。

此函式的連結

atomic_load(Modules)

查看原始碼 (自 OTP 19.0 起)
-spec atomic_load(Modules) -> ok | {error, [{Module, What}]}
                     when
                         Modules :: [Module | {Module, Filename, Binary}],
                         Module :: module(),
                         Filename :: file:filename(),
                         Binary :: binary(),
                         What ::
                             badfile | nofile | on_load_not_allowed | duplicated | not_purged |
                             sticky_directory | pending_on_load.

嘗試以原子方式載入清單 Modules 中的所有模組。

這表示如果任何模組發生問題,所有模組會同時載入,或都不載入。

載入可能會因為下列原因之一而失敗

  • badfile - 物件程式碼的格式不正確,或物件程式碼中的模組名稱不是預期的模組名稱。

  • nofile - 沒有目標碼的檔案存在。

  • on_load_not_allowed - 模組包含 -on_load 函式

  • duplicated - Modules 中多次包含模組。

  • not_purged - 因為程式碼的舊版本已存在,所以無法載入目標碼。

  • sticky_directory - 物件程式碼位於黏性目錄中。

  • pending_on_load - 先前載入的模組包含從未完成的 -on_load 函式。

如果變更程式碼時最小化應用程式不活動的時間很重要,請使用 prepare_loading/1finish_loading/1,而不是 atomic_load/1。以下是一個範例

{ok,Prepared} = code:prepare_loading(Modules),
%% Put the application into an inactive state or do any
%% other preparation needed before changing the code.
ok = code:finish_loading(Prepared),
%% Resume the application.
-spec clash() -> ok.

在程式碼路徑中的所有目錄中搜尋具有相同名稱的模組名稱,並將報告寫入 stdout

此函式的連結

clear_cache()

查看原始碼 (自 OTP 26.0 起)
-spec clear_cache() -> ok.

清除程式碼路徑快取。

如果目錄被快取,其快取會清除一次,然後在未來的遍歷中重新計算並再次快取。

若要清除單一路徑的快取,請將其重新新增至程式碼路徑(使用 add_path/2)或取代它(使用 replace_path/3)。若要停用所有快取,請使用 code:set_path(code:get_path()) 重設程式碼路徑。

一律返回 ok

-spec compiler_dir() -> file:filename().

傳回編譯器程式庫目錄。

等同於 code:lib_dir(compiler)

此函式的連結

coverage_support()

查看原始碼 (自 OTP 27.0 起)
-spec coverage_support() -> Supported when Supported :: boolean().

如果系統支援涵蓋率,則傳回 true,否則傳回 false

另請參閱: 原生覆蓋率支援

-spec del_path(NameOrDir) -> boolean() | {error, What}
                  when NameOrDir :: Name | Dir, Name :: atom(), Dir :: file:filename(), What :: bad_name.

從程式碼路徑中刪除目錄。

引數可以是原子 Name,在這種情況下,名稱為 .../Name[-Vsn][/ebin] 的目錄會從程式碼路徑中刪除。此外,完整的目錄名稱 Dir 可以指定為引數。

返回

  • true - 如果成功

  • false - 如果找不到目錄

  • {error, bad_name} - 如果引數無效

此函式的連結

del_paths(NamesOrDirs)

查看原始碼 (自 OTP 26.0 起)
-spec del_paths(NamesOrDirs) -> ok
                   when NamesOrDirs :: [Name | Dir], Name :: atom(), Dir :: file:filename().

從程式碼路徑中刪除多個目錄。

引數是原子或完整目錄名稱的列表。如果 Name 是原子,則名稱為 .../Name[-Vsn][/ebin] 的目錄會從程式碼路徑中刪除。

無論每個單獨的 NamesOrDirs 的有效性為何,皆一律返回 ok

-spec delete(Module) -> boolean() when Module :: module().

移除 Module 的目前程式碼,也就是說,Module 的目前程式碼會變成舊的。

這表示程序可以繼續執行模組中的程式碼,但無法對其進行外部函式呼叫。

如果成功,則返回 true,如果 Module 有舊程式碼必須先清除,或者如果 Module 不是(已載入的)模組,則返回 false

-spec ensure_loaded(Module) -> {module, Module} | {error, What}
                       when Module :: module(), What :: embedded | badfile | nofile | on_load_failure.

嘗試以與 load_file/1 相同的方式載入模組,除非模組已經載入。

如果同時呼叫此函式,則會確保在給定時間內只有一個程序嘗試載入該模組。

在嵌入模式下,它不會載入尚未載入的模組,而是返回 {error, embedded}。有關其他可能的錯誤原因描述,請參閱程式碼載入函式的錯誤原因

此函式的連結

ensure_modules_loaded(Modules)

檢視原始碼 (自 OTP 19.0 起)
-spec ensure_modules_loaded([Module]) -> ok | {error, [{Module, What}]}
                               when Module :: module(), What :: badfile | nofile | on_load_failure.

嘗試以與 load_file/1 相同的方式載入清單 Modules 中尚未載入的任何模組。

ensure_loaded/1 不同,即使在 embedded 模式下,也會載入模組。

如果成功則返回 ok,如果載入某些模組失敗,則返回 {error,[{Module,Reason}]}。有關其他可能的錯誤原因描述,請參閱程式碼載入函式的錯誤原因

此函式的連結

finish_loading(Prepared)

檢視原始碼 (自 OTP 19.0 起)
-spec finish_loading(Prepared) -> ok | {error, [{Module, What}]}
                        when
                            Prepared :: prepared_code(),
                            Module :: module(),
                            What :: not_purged | sticky_directory | pending_on_load.

嘗試載入先前由 prepare_loading/1 準備的所有模組的程式碼。

載入操作是原子性的,這表示要么所有模組同時載入,要么所有模組都不載入。

此函式可能會因以下錯誤原因之一而失敗

  • not_purged - 因為程式碼的舊版本已存在,所以無法載入目標碼。

  • sticky_directory - 物件程式碼位於黏性目錄中。

  • pending_on_load - 先前載入的模組包含從未完成的 -on_load 函式。

此函式的連結

get_coverage(Level, Module)

檢視原始碼 (自 OTP 27.0 起)
-spec get_coverage(Level, module()) -> Result
                      when
                          Level :: function | line | cover_id_line,
                          Result :: [{Entity, CoverageInfo}],
                          Entity :: {Function, Arity} | Line | CoverId,
                          CoverageInfo :: Covered | Counter,
                          Function :: atom(),
                          Arity :: arity(),
                          Line :: non_neg_integer(),
                          CoverId :: pos_integer(),
                          Covered :: boolean(),
                          Counter :: non_neg_integer().

傳回模組 Modulefunctionline 涵蓋率資料。

如果 Level 為 function,則根據給定模組的覆蓋模式返回該模組的函式覆蓋率。

  • function - 對於模組 Module 中的每個函式,返回一個布林值,指示該函式是否至少執行過一次。

  • function_counters - 對於模組 Module 中的每個函式,返回一個整數,表示該行已執行的次數。

  • line - 對於模組 Module 中的每個函式,返回一個布林值,指示該函式是否至少執行過一次。

  • line_counters - 對於模組 Module 中的每個函式,返回一個布林值,指示該函式是否至少執行過一次(請注意,在此模式下,無法擷取每個函式已執行的次數)。

如果 Level 為 line,則根據給定模組的覆蓋模式返回該模組的程式碼行覆蓋率。

  • line - 對於模組中的每個可執行行,返回一個布林值,指示該行是否至少執行過一次。

  • line_counters - 對於模組中的每個可執行行,返回一個整數,表示該行已執行的次數。

Level cover_id_linecover 工具使用。

失敗情況

  • badarg - 如果 Level 不是 functionline

  • badarg - 如果 Module 不是原子。

  • badarg - 如果 Module 沒有指向已載入的模組。

  • badarg - 如果 Module 不是以 none 以外的其他覆蓋模式載入的。

  • badarg - 如果 Level 為 lineModule 未以啟用 lineline_counters 的模式載入。

  • badarg - 如果執行階段系統不支援覆蓋率。

另請參閱: 原生覆蓋率支援

此函式的連結

get_coverage_mode()

檢視原始碼 (自 OTP 27.0 起)
-spec get_coverage_mode() -> Mode when Mode :: coverage_mode().

傳回由 erl 的選項 +JPcoverset_coverage_mode/1 設定的涵蓋率模式。

失敗

  • badarg - 如果執行階段系統不支援覆蓋率。

另請參閱: 原生覆蓋率支援

此函式的連結

get_coverage_mode(Module)

檢視原始碼 (自 OTP 27.0 起)
-spec get_coverage_mode(Module) -> Mode when Module :: module(), Mode :: coverage_mode().

取得指定模組的涵蓋率模式。

失敗情況

  • badarg - 如果 Module 不是原子。

  • badarg - 如果 Module 沒有指向已載入的模組。

  • badarg - 如果執行階段系統不支援覆蓋率。

另請參閱: 原生覆蓋率支援

此函式的連結

get_doc(Module)

檢視原始碼 (自 OTP 23.0 起)
-spec get_doc(Mod) -> {ok, Res} | {error, Reason}
                 when
                     Mod :: module(),
                     Res ::
                         #docs_v1{anno :: term(),
                                  beam_language :: term(),
                                  format :: term(),
                                  module_doc :: term(),
                                  metadata :: term(),
                                  docs :: term()},
                     Reason :: non_existing | missing | file:posix().

如果可用,則傳回 ModuleEEP 48 風格文件。

如果在程式碼路徑中找不到 Module,此函式將返回 {error,non_existing}

如果找不到文件,此函式會嘗試從模組中的除錯資訊產生文件。如果沒有除錯資訊,此函式將返回 {error,missing}

有關文件區塊的更多資訊,請參閱 Kernel 使用者指南中的文件儲存和格式

此函式的連結

get_mode()

檢視原始碼 (自 OTP R16B 起)
-spec get_mode() -> embedded | interactive.

傳回描述程式碼伺服器模式的原子:interactiveembedded

當外部實體(例如 IDE)為正在執行的節點提供額外程式碼時,此資訊非常有用。如果程式碼伺服器處於互動模式,則只需將路徑新增至程式碼。如果程式碼伺服器處於嵌入模式,則必須使用 load_binary/3 載入程式碼。

此函式的連結

get_object_code(Module)

查看原始碼
-spec get_object_code(Module) -> {Module, Binary, Filename} | error
                         when Module :: module(), Binary :: binary(), Filename :: file:filename().

如果在程式碼路徑中找到,則傳回模組 Module 的物件程式碼。

如果成功,則返回 {Module, Binary, Filename},否則返回 errorBinary 是一個二進位資料物件,其中包含模組的物件碼。如果要將程式碼載入分散式系統中的遠端節點,這非常有用。例如,在節點 Node 上載入模組 Module 的方式如下

...
{_Module, Binary, Filename} = code:get_object_code(Module),
erpc:call(Node, code, load_binary, [Module, Filename, Binary]),
...
-spec get_path() -> Path when Path :: [Dir :: file:filename()].

傳回程式碼路徑。

-spec is_loaded(Module) -> {file, Loaded} | false when Module :: module(), Loaded :: loaded_filename().

檢查是否已載入 Module

如果是,則返回 {file, Loaded},否則返回 false

通常,Loaded 是從中取得程式碼的絕對檔案名稱 Filename。如果模組是預先載入的(請參閱 script(4)),則 Loaded =:= preloaded。如果模組是 Cover 編譯的(請參閱 cover),則 Loaded =:= cover_compiled

-spec is_sticky(Module) -> boolean() when Module :: module().

如果 Module 是從黏性目錄載入的模組名稱(換句話說:嘗試重新載入該模組將會失敗),則傳回 true;如果 Module 不是已載入的模組或不是黏性的,則傳回 false

-spec lib_dir() -> file:filename().

傳回程式庫目錄 $OTPROOT/lib,其中 $OTPROOT 是 Erlang/OTP 的根目錄。

範例

1> code:lib_dir().
"/usr/local/otp/lib"
-spec lib_dir(Name) -> file:filename() | {error, bad_name} when Name :: atom().

傳回應用程式 Name程式庫目錄(頂層目錄)路徑,該應用程式位於 $OTPROOT/lib 下或以環境變數 ERL_LIBS 參照的目錄中。

如果程式碼路徑中存在一個名為 NameName-Vsn 的常規目錄,且其中包含 ebin 子目錄,則返回此目錄的路徑(而不是 ebin 目錄)。

如果該目錄指向封存檔中的目錄,則會在返回路徑之前移除封存檔名稱。例如,如果路徑中存在目錄 /usr/local/otp/lib/mnesia-4.2.2.ez/mnesia-4.2.2/ebin,則返回 /usr/local/otp/lib/mnesia-4.2.2/ebin。這表示無論應用程式是否位於封存檔中,應用程式的程式庫目錄都相同。

警告

封存檔是實驗性的。在未來的版本中,可能會移除它們或變更其行為。

範例

> code:lib_dir(mnesia).
"/usr/local/otp/lib/mnesia-4.23"

如果 Name 不是 $OTPROOT/lib 下或透過環境變數 ERL_LIBS 指向的目錄中的應用程式名稱,則返回 {error, bad_name}。如果 Name 的類型錯誤,則會出現例外狀況而失敗。

警告

為了保持回溯相容性,也允許 Name 為字串。這在未來版本中可能會變更。

此函式已過時。code:lib_dir/2 已過時;此功能將在未來的版本中移除。
-spec lib_dir(Name, SubDir) -> file:filename() | {error, bad_name} when Name :: atom(), SubDir :: atom().

傳回應用程式頂層目錄下的子目錄路徑。

變更

此函式是封存檔支援的一部分,封存檔支援是一個實驗性功能,將在未來的版本中變更或移除。

通常,子目錄位於應用程式的頂層目錄下,但是當應用程式至少部分位於封存檔中時,情況會有所不同。某些子目錄可以以常規目錄的形式存在,而其他子目錄則位於封存檔中。不會檢查此目錄是否存在。

請改用 code:lib_dir/1filename:join/2,而不是使用此函式。

範例

1> filename:join(code:lib_dir(megaco), "priv").
"/usr/local/otp/lib/megaco-3.9.1.1/priv"

如果 NameSubDir 的類型錯誤,則會出現例外狀況而失敗。

-spec load_abs(Filename) -> load_ret() when Filename :: file:filename().

等同於 load_file(Module),不同之處在於 Filename 是絕對或相對檔名。

不會搜尋程式碼路徑。它返回的值與 load_file/1 的方式相同。請注意,Filename 不得包含副檔名(例如,.beam),因為 load_abs/1 會新增正確的副檔名。

此函式的連結

load_binary(Module, Filename, Binary)

查看原始碼
-spec load_binary(Module, Filename, Binary) -> {module, Module} | {error, What}
                     when
                         Module :: module(),
                         Filename :: loaded_filename(),
                         Binary :: binary(),
                         What :: badarg | load_error_rsn().

從二進位資料載入物件程式碼。

此函式可用於在遠端 Erlang 節點上載入物件碼。引數 Binary 必須包含 Module 的物件碼。Filename 僅供程式碼伺服器記錄 Module 的物件碼來自哪個檔案。因此,程式碼伺服器不會開啟和讀取 Filename

如果成功,則返回 {module, Module},如果載入失敗,則返回 {error, Reason}。有關可能的錯誤原因描述,請參閱程式碼載入函式的錯誤原因

-spec load_file(Module) -> load_ret() when Module :: module().

嘗試使用程式碼路徑載入 Erlang 模組 Module

它會搜尋與所使用 Erlang 機器相對應的副檔名的物件碼檔案,例如 Module.beam。如果在物件碼中找到的模組名稱與名稱 Module 不同,則載入會失敗。請使用 load_binary/3 載入模組名稱與檔案名稱不同的物件碼。

如果成功,則返回 {module, Module},如果載入失敗,則返回 {error, Reason}。有關可能的錯誤原因描述,請參閱程式碼載入函式的錯誤原因

此函式的連結

modified_modules()

檢視原始碼 (自 OTP 20.0 起)
-spec modified_modules() -> [module()].

傳回目前已載入的所有模組的清單,其中 module_status/1 傳回 modified

另請參閱 all_loaded/0

此函式的連結

module_status()

檢視原始碼 (自 OTP 23.0 起)
-spec module_status() -> [{module(), module_status()}].

詳細資訊請參閱 module_status/1all_loaded/0

此函式的連結

module_status(Module)

檢視原始碼 (自 OTP 20.0 起)
-spec module_status(Module :: module() | [module()]) -> module_status() | [{module(), module_status()}].

傳回 Module 相對於磁碟上物件檔案的狀態。

模組的狀態可以是下列其中之一

  • not_loaded - 如果目前未載入 Module

  • loaded - 如果已載入 Module,且物件檔案存在並包含相同的程式碼。

  • removed - 如果已載入 Module,但在程式碼路徑中找不到對應的物件檔案。

  • modified - 如果已載入 Module,但物件檔案包含具有不同 MD5 檢查碼的程式碼。

預先載入的模組一律報告為 loaded,而不檢查磁碟上的內容。如果物件檔案存在,則 Cover 編譯的模組一律報告為 modified,否則報告為 removed。載入路徑為空字串(這是自動產生程式碼的慣例)的模組只會報告為 loadednot_loaded

另請參閱 modified_modules/0

-spec objfile_extension() -> nonempty_string().

返回對應於所使用 Erlang 機器的目標碼檔案副檔名。

對於官方 Erlang/OTP 版本,傳回值一律為 .beam

此函式的連結

prepare_loading(Modules)

檢視原始碼 (自 OTP 19.0 起)
-spec prepare_loading(Modules) -> {ok, Prepared} | {error, [{Module, What}]}
                         when
                             Modules :: [Module | {Module, Filename, Binary}],
                             Module :: module(),
                             Filename :: file:filename(),
                             Binary :: binary(),
                             Prepared :: prepared_code(),
                             What :: badfile | nofile | on_load_not_allowed | duplicated.

準備載入列表 Modules 中的模組。

呼叫 finish_loading(Prepared) 以完成載入。

此函式可能會因以下錯誤原因之一而失敗

  • badfile - 物件程式碼的格式不正確,或物件程式碼中的模組名稱不是預期的模組名稱。

  • nofile - 沒有目標碼的檔案存在。

  • on_load_not_allowed - 模組包含 -on_load 函式

  • duplicated - Modules 中多次包含模組。

-spec priv_dir(Name) -> file:filename() | {error, bad_name} when Name :: atom().

返回應用程式中 priv 目錄的路徑。

警告

為了保持回溯相容性,也允許 Name 為字串。這在未來版本中可能會變更。

-spec purge(Module) -> boolean() when Module :: module().

清除 Module 的程式碼,也就是移除標記為舊的程式碼。

如果某些程序仍然停留在舊程式碼中,這些程序會在移除程式碼之前被終止。

變更

自 Erlang/OTP 20.0 起,只有當程序直接參考程式碼時,才被視為停留在程式碼中。如需更多資訊,請參閱 erlang:check_process_code/3 的文件,該文件用於判斷程序是否停留在程式碼中。

如果成功且需要終止任何程序,則返回 true,否則返回 false

此函式的連結

replace_path(Name, Dir)

查看原始碼
-spec replace_path(Name, Dir) -> replace_path_ret() when Name :: atom(), Dir :: file:filename().

等同於 replace_path(Name, Dir, nocache)

此函式的連結

replace_path(Name, Dir, Cache)

檢視原始碼 (自 OTP 26.0 起)
-spec replace_path(Name, Dir, cache()) -> replace_path_ret() when Name :: atom(), Dir :: file:filename().

將程式碼路徑中名為 .../Name[-Vsn][/ebin] 的舊目錄出現位置,取代為 Dir

如果 Name 不存在,它會在程式碼路徑的最後新增新的目錄 Dir。新目錄也必須命名為 .../Name[-Vsn][/ebin]。如果將新版本的目錄(函式庫)新增至執行中的系統,則應使用此函式。

引數 Cache 控制是否應在第一次遍歷時快取目錄的內容。如果 Cachecache,目錄內容將被快取;如果 Cachenocache,則不會被快取。

返回

  • true - 如果成功

  • {error, bad_name} - 如果找不到 Name

  • {error, bad_directory} - 如果 Dir 不存在

  • {error, {badarg, [Name, Dir]}} - 如果 NameDir 無效

此函式的連結

reset_coverage(Module)

檢視原始碼 (自 OTP 27.0 起)
-spec reset_coverage(Module) -> ok when Module :: module().

重設模組 Module 的覆蓋率資訊。

如果 涵蓋率模式functionline,則所有用於追蹤已執行函式或行的 Module 布林值都會設定為 false

如果涵蓋率模式為 function_countersline_counters,則 Module 的所有計數器都會重設為零。

失敗情況

  • badarg - 如果 Module 不是原子。

  • badarg - 如果 Module 沒有指向已載入的模組。

  • badarg - 如果 Module 未啟用涵蓋率載入。

  • badarg - 如果執行階段系統不支援覆蓋率。

另請參閱: 原生覆蓋率支援

-spec root_dir() -> file:filename().

返回 Erlang/OTP 的根目錄,也就是其安裝所在的目錄。

範例

1> code:root_dir().
"/usr/local/otp"
此函式的連結

set_coverage_mode(Mode)

檢視原始碼 (自 OTP 27.0 起)
-spec set_coverage_mode(Mode) -> OldMode when Mode :: coverage_mode(), OldMode :: coverage_mode().

設定後續載入模組的覆蓋率模式,類似於 erl 的選項 +JPcover

涵蓋率模式將對此呼叫後載入的程式碼產生以下影響

  • function - 所有載入的模組都將被檢測,以追蹤已執行哪些函式。可以透過呼叫 get_coverage(function, Module) 來擷取有關已執行哪些函式的資訊。

  • function_counters - 所有載入的模組都將被檢測,以計算每個函式執行的次數。可以透過呼叫 get_coverage(function, Module) 來擷取有關每個函式已執行多少次的資訊。

  • line - 當載入使用 line_coverage 選項編譯的模組時,它們將被檢測以追蹤已執行哪些程式碼行。可以透過呼叫 get_coverage(line, Module) 來擷取有關已執行哪些行的資訊,並且可以透過呼叫 get_coverage(function, Module) 來擷取有關已執行哪些函式的資訊。

  • line_counters - 當載入使用 line_coverage 選項編譯的模組時,它們將被檢測以計算每行程式碼執行的次數。可以透過呼叫 get_coverage(line, Module) 來擷取有關每行程式碼已執行多少次的資訊,並且可以透過呼叫 get_coverage(function, Module) 來擷取有關已執行哪些函式的資訊(請注意,在此模式下,**無法**擷取每個函式已執行次數的計數器)。

  • none - 將載入模組,而不會進行涵蓋率檢測。

返回先前的涵蓋率模式。

失敗情況

  • badarg - 如果 Mode 不是有效的涵蓋率模式。

  • badarg - 如果執行階段系統不支援覆蓋率。

另請參閱: 原生覆蓋率支援

-spec set_path(Path) -> set_path_ret() when Path :: [Dir :: file:filename()].

等同於 set_path(PathList, nocache)

此函式的連結

set_path(PathList, Cache)

檢視原始碼 (自 OTP 26.0 起)
-spec set_path(Path, cache()) -> set_path_ret() when Path :: [Dir :: file:filename()].

將程式碼路徑設定為目錄列表 Path

引數 Cache 控制是否應在第一次遍歷時快取目錄的內容。如果 Cachecache,目錄內容將被快取;如果 Cachenocache,則不會被快取。

返回

  • true - 如果成功

  • {error, bad_directory} - 如果任何 Dir 不是目錄名稱

-spec soft_purge(Module) -> boolean() when Module :: module().

清除 Module 的程式碼,也就是移除標記為舊的程式碼,但僅限於其中沒有持續執行的程序。

變更

自 Erlang/OTP 20.0 起,只有當程序直接參考程式碼時,才被視為停留在程式碼中。如需更多資訊,請參閱 erlang:check_process_code/3 的文件,該文件用於判斷程序是否停留在程式碼中。

如果因為舊程式碼中仍有程序停留而無法清除模組,則返回 false,否則返回 true

-spec stick_dir(Dir) -> ok | error when Dir :: file:filename().

Dir 標記為黏性的。

如果成功,則返回 ok,否則返回 error

-spec unstick_dir(Dir) -> ok | error when Dir :: file:filename().

取消標記為黏性的目錄。

如果成功,則返回 ok,否則返回 error

此函式的連結

where_is_file(Filename)

查看原始碼
-spec where_is_file(Filename) -> non_existing | Absname
                       when Filename :: file:filename(), Absname :: file:filename().

在程式碼路徑中搜尋 Filename,這是一個任意類型的檔案。

如果找到,則返回完整名稱。如果找不到該檔案,則返回 non_existing。此函式可能很有用,例如,用於尋找應用程式資源檔案。

-spec which(Module) -> Which when Module :: module(), Which :: loaded_filename() | non_existing.

如果模組尚未載入,此函式會在程式碼路徑中搜尋第一個包含 Module 目標碼的檔案,並返回絕對檔案名稱。

  • 如果載入模組,則返回包含已載入物件程式碼的檔案名稱。

  • 如果模組是預先載入的,則返回 preloaded

  • 如果模組是 Cover 編譯的,則返回 cover_compiled

  • 如果找不到模組,則返回 non_existing