目錄

名稱

perlmroapi - Perl 方法解析外掛程式介面

說明

從 Perl 5.10.1 開始,有一個新的介面可以外掛並使用除了預設(線性深度優先搜尋)以外的方法解析順序。在 5.10.0 中新增的 C3 方法解析順序已重新實作為一個外掛程式,而沒有變更其 Perl 空間介面。

每個外掛程式應提供下列結構以註冊自身

struct mro_alg {
    AV *(*resolve)(pTHX_ HV *stash, U32 level);
    const char *name;
    U16 length;
    U16 kflags;
    U32 hash;
};

並呼叫 Perl_mro_register

Perl_mro_register(aTHX_ &my_mro_alg);
resolve

指向下列所述的線性化函數。

name

MRO 的名稱,以 ISO-8859-1 或 UTF-8 編碼。

length

名稱的長度。

kflags

如果名稱以 UTF-8 編碼,請將此設定為 HVhek_UTF8。此值會直接傳遞為參數 kflagshv_common()

hash

MRO 名稱的預先計算雜湊值,或 0。

Callbacks

resolve 函數會被呼叫以使用此 MRO 為指定的儲存空間產生線性化的 ISA。它會以指向儲存空間的指標和 層級 0 被呼叫。核心在呼叫函數時總是將 層級 設定為 0 - 提供參數以允許實作在需要遞迴時追蹤深度。

此函數應傳回對包含字串 SV 的陣列的參考,其中包含父類別名稱的順序。類別名稱應為在儲存空間上呼叫 HvENAME() 的結果。在 HvENAME() 傳回 null 的情況下,應改用 HvNAME()

呼叫方負責增加傳回陣列的參考計數,如果它要保留結構。因此,如果您已建立暫時值且未保留任何指標,請使用 sv_2mortal() 以確保正確處置。如果您已快取傳回值,請傳回指向它的指標,而不要變更參考計數。

快取

計算 MRO 可能很昂貴。此實作提供了一個快取,您可以在其中儲存單一的 SV *,或任何可以轉換為 SV * 的東西,例如 AV *。若要讀取您的私人值,請使用巨集 MRO_GET_PRIVATE_DATA(),將其傳遞給快取中的 mro_meta 結構,以及指向您的 mro_alg 結構的指標

meta = HvMROMETA(stash);
private_sv = MRO_GET_PRIVATE_DATA(meta, &my_mro_alg);

若要設定您的私人值,請呼叫 Perl_mro_set_private_data()

Perl_mro_set_private_data(aTHX_ meta, &c3_alg, private_sv);

私人資料快取將擁有對 private_sv 的參考,這與 hv_store() 擁有對您傳遞給它的值的參考的方式非常類似。

範例

有關 MRO 實作的範例,請參閱 ext/mro/mro.xs 中的 S_mro_get_linear_isa_c3()BOOT: 區段,以及 mro_core.c 中的 S_mro_get_linear_isa_dfs()

作者

Brandon L Black 編寫了 perl 核心中的 C3 MRO 和可切換 MRO 的實作。Nicholas Clark 建立了可插入式介面,將 Brandon 的實作重新整理為可與之搭配運作,並撰寫了這份文件。