目錄

名稱

UNIVERSAL - 所有類別的基本類別(受祝福的參考)

語法

my $obj_is_io    = $fd->isa("IO::Handle");
my $cls_is_io    = Class->isa("IO::Handle");

my $obj_does_log = $obj->DOES("Logger");
my $cls_does_log = Class->DOES("Logger");

my $obj_sub      = $obj->can("print");
my $cls_sub      = Class->can("print");

my $eval_sub     = eval { $ref->can("fandango") };
my $ver          = $obj->VERSION;

# but never do this!
my $is_io        = UNIVERSAL::isa($fd, "IO::Handle");
my $sub          = UNIVERSAL::can($obj, "print");

說明

UNIVERSAL 是所有受祝福參考繼承的基本類別。請參閱 perlobj

UNIVERSAL 提供下列方法

$obj->isa( TYPE )
CLASS->isa( TYPE )
eval { VAL->isa( TYPE ) }

其中

TYPE

是套件名稱

$obj

是受祝福的參考或套件名稱

CLASS

是套件名稱

VAL

是上述任一項或未受祝福的參考

當用作執行個體或類別方法($obj->isa( TYPE ))時,如果 $obj 已受祝福進入套件 TYPE 或繼承自套件 TYPEisa 會傳回 true

當用作類別方法(CLASS->isa( TYPE ),有時稱為靜態方法)時,如果 CLASS 繼承自(或本身就是)套件 TYPE 的名稱或繼承自套件 TYPEisa 會傳回 true

如果您不確定您擁有什麼(VAL 案例),請將方法呼叫包覆在 eval 區塊中,以在 VAL 未定義或未祝福的參考中捕捉例外。 isa 算子 是在這種情況下僅傳回 false 的替代方案,因此不需要 eval

如果您想要確定您呼叫 isa 是作為方法,而不是類別,請先使用 Scalar::Util 中的 blessed 檢查呼叫對象。

use Scalar::Util 'blessed';

if ( blessed( $obj ) && $obj->isa("Some::Class") ) {
    ...
}
$obj->DOES( ROLE )
CLASS->DOES( ROLE )

DOES 檢查物件或類別是否執行角色 ROLE。角色是一個特定行為的名稱群組(通常是特定名稱和簽章的方法),類似於類別,但本身不一定是完整的類別。例如,記錄或序列化可能是角色。

DOESisa 很相似,因為如果任一者為 true,您就知道您呼叫方法的物件或類別可以執行特定行為。但是,DOESisa 不同之處在於它不在乎呼叫對象如何執行操作,只在乎它是否執行。(isa 當然要求繼承關係。其他關係包括聚合、委派和模擬。)

預設情況下,Perl 中的類別只執行 UNIVERSAL 角色,以及其繼承中所有類別的角色。換句話說,預設情況下 DOESisa 的回應相同。

角色和類別之間存在關係,因為每個類別都暗示存在同名角色。繼承和角色之間也存在關係,因為繼承自祖先類別的子類別會隱含執行其父類別執行的任何角色。因此,您可以安全地使用 DOES 取代 isa,因為它會在 isa 會傳回 true 的所有地方傳回 true(前提是任何覆寫的 DOES isa 方法都有適當的行為)。

$obj->can( METHOD )
CLASS->can( METHOD )
eval { VAL->can( METHOD ) }

can 檢查物件或類別是否有稱為 METHOD 的方法。如果有,則傳回子程式的參考。如果沒有,則傳回 undef。這包含 $objCLASSVAL 繼承或匯入的方法。

can 無法得知物件是否能透過 AUTOLOAD 提供方法(除非物件的類別已適當地覆寫 can),因此傳回值 undef 並不一定表示物件無法處理方法呼叫。為了解決這個問題,有些模組作者會使用前向宣告(請參閱 perlsub)來處理他們會透過 AUTOLOAD 處理的方法。對於此類「虛擬」子程式,can 仍會傳回程式碼參考,當呼叫時,將會轉到 AUTOLOAD。如果沒有提供合適的 AUTOLOAD,呼叫程式碼參考會導致錯誤。

您可以將 can 呼叫為類別(靜態)方法或物件方法。

同樣地,關於擁有有效呼叫目標的規則適用於此 -- 如果您需要特別小心,請使用 eval 區塊或 blessed

VERSION ( [ REQUIRE ] )

VERSION 會傳回物件所祝福的套件中 $VERSION 變數的值。如果給定 REQUIRE,它會執行比較,如果套件版本小於或等於 REQUIRE,或 $VERSIONREQUIRE 不是「寬鬆」版本號碼(如 version 模組所定義),則會執行 die。

VERSION 的傳回值實際上會是使用套件 $VERSION 標量字串化的版本物件,保證等效,但可能不會完全是 $VERSION 標量的內容。如果您要取得 $VERSION 的實際內容,請改用 $CLASS::VERSION

VERSION 可以呼叫為類別(靜態)方法或物件方法。

WARNINGS

注意: can 直接使用 Perl 的內部程式碼來尋找方法,而 isa 使用非常相似的策略和快取策略。如果 Perl 程式碼動態變更任何套件中的 @ISA,這可能會造成奇怪的效果。

您可透過 Perl 或 XS 程式碼新增其他方法至 UNIVERSAL 類別。您不需要使用 use UNIVERSAL 來讓這些方法可用於您的程式(您也不應該這麼做)。

匯出

無。

此文件的前一版本建議將 isa 作為函式使用,以判斷參考的類型

$yes = UNIVERSAL::isa($h, "HASH");
$yes = UNIVERSAL::isa("Foo", "Bar");

問題在於此程式碼永遠不會在任何類別中呼叫覆寫的 isa 方法。相反地,對於第一個案例,請使用 Scalar::Util 中的 reftype

use Scalar::Util 'reftype';

$yes = reftype( $h ) eq "HASH";

以及 isa 的方法形式,用於第二個案例

$yes = Foo->isa("Bar");