如何检查Perl变量是否为PDL格式(即是一个小提琴)?

时间:2016-04-25 21:33:54

标签: perl pdl

我正在使用PDL。如果给定变量$foo可以是散列引用,数组引用,标量或小提琴(可以为空或空),我怎么能判断它是不是很合适?

2 个答案:

答案 0 :(得分:3)

您可以使用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

答案 1 :(得分:3)

检查某个类是否属于某个类的典型方法是使用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") ) { ... }