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 ) }
其中
當用作執行個體或類別方法($obj->isa( TYPE )
)時,如果 $obj 已受祝福進入套件 TYPE
或繼承自套件 TYPE
,isa
會傳回 true。
當用作類別方法(CLASS->isa( TYPE )
,有時稱為靜態方法)時,如果 CLASS
繼承自(或本身就是)套件 TYPE
的名稱或繼承自套件 TYPE
,isa
會傳回 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
。角色是一個特定行為的名稱群組(通常是特定名稱和簽章的方法),類似於類別,但本身不一定是完整的類別。例如,記錄或序列化可能是角色。
DOES
和 isa
很相似,因為如果任一者為 true,您就知道您呼叫方法的物件或類別可以執行特定行為。但是,DOES
與 isa
不同之處在於它不在乎呼叫對象如何執行操作,只在乎它是否執行。(isa
當然要求繼承關係。其他關係包括聚合、委派和模擬。)
預設情況下,Perl 中的類別只執行 UNIVERSAL
角色,以及其繼承中所有類別的角色。換句話說,預設情況下 DOES
對 isa
的回應相同。
角色和類別之間存在關係,因為每個類別都暗示存在同名角色。繼承和角色之間也存在關係,因為繼承自祖先類別的子類別會隱含執行其父類別執行的任何角色。因此,您可以安全地使用 DOES
取代 isa
,因為它會在 isa
會傳回 true 的所有地方傳回 true(前提是任何覆寫的 DOES
和 isa
方法都有適當的行為)。
$obj->can( METHOD )
CLASS->can( METHOD )
eval { VAL->can( METHOD ) }
can
檢查物件或類別是否有稱為 METHOD
的方法。如果有,則傳回子程式的參考。如果沒有,則傳回 undef。這包含 $obj
、CLASS
或 VAL
繼承或匯入的方法。
can
無法得知物件是否能透過 AUTOLOAD 提供方法(除非物件的類別已適當地覆寫 can
),因此傳回值 undef 並不一定表示物件無法處理方法呼叫。為了解決這個問題,有些模組作者會使用前向宣告(請參閱 perlsub)來處理他們會透過 AUTOLOAD 處理的方法。對於此類「虛擬」子程式,can
仍會傳回程式碼參考,當呼叫時,將會轉到 AUTOLOAD。如果沒有提供合適的 AUTOLOAD,呼叫程式碼參考會導致錯誤。
您可以將 can
呼叫為類別(靜態)方法或物件方法。
同樣地,關於擁有有效呼叫目標的規則適用於此 -- 如果您需要特別小心,請使用 eval
區塊或 blessed
。
VERSION ( [ REQUIRE ] )
VERSION
會傳回物件所祝福的套件中 $VERSION
變數的值。如果給定 REQUIRE
,它會執行比較,如果套件版本小於或等於 REQUIRE
,或 $VERSION
或 REQUIRE
不是「寬鬆」版本號碼(如 version 模組所定義),則會執行 die。
VERSION
的傳回值實際上會是使用套件 $VERSION
標量字串化的版本物件,保證等效,但可能不會完全是 $VERSION
標量的內容。如果您要取得 $VERSION
的實際內容,請改用 $CLASS::VERSION
。
VERSION
可以呼叫為類別(靜態)方法或物件方法。
注意: 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");