【发布时间】:2016-08-19 11:42:05
【问题描述】:
我正在使用PDL。如果给定变量$foo,它可以是哈希引用、数组引用、标量或piddle(可以为空或null),我如何判断它是否是piddle?
【问题讨论】:
我正在使用PDL。如果给定变量$foo,它可以是哈希引用、数组引用、标量或piddle(可以为空或null),我如何判断它是否是piddle?
【问题讨论】:
检查某物是否属于某个类的典型方法是使用isa。
if( $thing->isa("PDL") ) { ... }
这尊重inheritance。只要$thing 是 PDL 的子类(或者说是),上面的方法就可以工作。这可以保护您免受自定义子类和 PDL 本身更改的影响。下面是一个例子。
use strict;
use warnings;
use v5.10;
package MyPDL;
our @ISA = qw(PDL);
package main;
use PDL;
use Scalar::Util qw(blessed);
my $stuff = pdl [1..10];
say blessed $stuff; # PDL
say "\$stuff is a PDL thing" if $stuff->isa("PDL"); # true
my $bar = MyPDL->new([1..10]);
say blessed $bar; # MyPDL
say "\$bar is a PDL thing" if $bar->isa("PDL"); # true
但是,方法调用不适用于非引用和未祝福的引用;如果你尝试,你会得到一个错误。您可以通过两种方式解决此问题。首先是使用eval BLOCK 来捕获错误,就像其他语言中的try。
if( eval { $thing->isa("PDL") } ) { ... }
如果$thing 不是对象,eval 将捕获错误并返回 false。如果$thing是一个对象,它会调用isa并返回结果。
缺点是这将捕获任何错误,包括来自isa 的错误。很少见,但它会发生。为避免这种情况,请先使用Scalar::Util's blessed() 确定$thing 是否为对象。
use Scalar::Util qw(blessed):
if( blessed $thing && $thing->isa("PDL") ) { ... }
【讨论】:
您可以使用Scalar::Util 来确定变量是否为:
blessed函数)reftype函数)您可以使用isa 方法来确定对象是特定类的实例还是继承自该类。
Piddles 是简单的 PDL 对象,即被祝福到 PDL 类中的东西,所以
$foo->isa('PDL')
如果$foo 是一个谜,将返回true。
大家一起:
use strict;
use warnings 'all';
use 5.010;
use PDL;
use Scalar::Util qw(blessed reftype);
my $scalar = 19;
my $arrayref = [ qw(foo bar) ];
my $hashref = { baz => 'qux' };
my $piddle = pdl [ 1..10 ];
foreach my $item ($scalar, $arrayref, $hashref, $piddle) {
my $reftype;
if ( defined(blessed($item)) ) {
say 'piddle' if $item->isa('PDL');
}
elsif ( defined($reftype = reftype($item)) ) {
say $reftype;
}
else {
say 'Not a reference';
}
}
输出:
Not a reference
ARRAY
HASH
piddle
【讨论】:
isa而不是reftype来尊重继承,这个答案会更好。
blessed。我什至不知道blessed 返回了类型。