【问题标题】:How can I check if a Perl variable is in PDL format (i.e. is a piddle)?如何检查 Perl 变量是否为 PDL 格式(即是一个 piddle)?
【发布时间】:2016-08-19 11:42:05
【问题描述】:

我正在使用PDL。如果给定变量$foo,它可以是哈希引用、数组引用、标量或piddle(可以为空或null),我如何判断它是否是piddle?

【问题讨论】:

    标签: perl pdl


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      您可以使用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 返回了类型。
      • @Schwern 谢谢,已修复。现在我觉得我的回答只是对你的抄袭:-/
      • 我可以用两种不同的方式说同一件事。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-20
      • 1970-01-01
      • 1970-01-01
      • 2016-03-28
      相关资源
      最近更新 更多