内容

名称

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 模块定义),那么它将死亡。

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");