【问题标题】:Perl: proper way to check ref of a hashref in one swoop?Perl:一口气检查hashref的引用的正确方法?
【发布时间】:2012-12-05 19:57:38
【问题描述】:

给定示例代码:

foo(bar=>"test");
foo(bar=>["test"]);

sub foo {
   my $args = {@_};

   say ref($args->{bar});
   say ref(\$args->{bar});
}

输出:

{预期为空白}
标量
阵列
参考文献


我想测试的是检查传递的是标量还是数组的最佳方法。比如:

given( ref($args->{bar}) ){
   when "SCALAR" { }
   when "ARRAY"  { }
}

我可以连接这两种 ref 类型并执行 regex-when,但这效率低下。我也可以像下面这样测试它,但不确定这是否是首选:

if    ( ref(\$args->{bar}) eq "SCALAR" ) { ... }
elsif ( ref( $args->{bar}) eq "ARRAY"  ) { ... }
else  { return; }

【问题讨论】:

  • 我没有看到不做像if (!ref $args->{bar}) { # scalar case } elsif ("ARRAY" eq ref $args->{bar}) { # handle array} 这样简单的事情的令人信服的理由。
  • @MoritzBunkus:我认为这可能是要走的路。

标签: perl ref


【解决方案1】:

您不是要区分标量和数组。在这两种情况下你都会得到一个标量。您正在尝试区分非引用和对数组的引用。

if (!ref($x) || ref($x) eq 'ARRAY') {
   # Non-ref or ref to array.
   ...
}

if (!ref($x)) {
   # Non-ref
   ...
}
elsif (ref($x) eq 'ARRAY') {
   # Ref to array.
   ...
}

for (ref($x)) {
   if (!$_) {
      # Non-ref
      ...
   }
   elsif ($_ eq 'ARRAY') {
      # Ref to array.
      ...
   }
}

my $ref_type = ref($x);
if (!$ref_type) {
   # Non-ref
   ...
}
elsif ($ref_type eq 'ARRAY') {
   # Ref to array.
   ...
}

或(假设仅允许使用这两种类型的值)

if (ref($x)) {
   # Ref to array.
   ...
} else {
   # Non-ref
   ...
}

(请注意,Scalar::Util 的 reftype 实际上获取了 ref 类型。ref 可以返回类名而不是引用类型。)

请注意,根据存储类型区分值在 Perl 中是一种糟糕的设计。它一定有问题,因为它破坏了重载的对象。

【讨论】:

    【解决方案2】:

    给定范围内的编译指示

    use feature qw/ say switch /;
    

    你可以使用

    sub foo {
      my($args) = { @_ };
    
      given (ref $args->{bar}) {
        say "plain scalar '$args->{bar}'"
          when "";
    
        say "array, length=@{[scalar @{ $args->{bar} }]}"
          when "ARRAY";
    
        default { die "unexpected: $args->{bar}" }
      }
    }
    

    输出:

    纯标量“测试”
    数组,长度=1

    您的问题很抽象,但如果您更了解您想做什么,我们可以针对您的具体情况提供更具体、更有帮助的建议。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-07
      • 1970-01-01
      • 1970-01-01
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      • 2010-10-17
      • 1970-01-01
      相关资源
      最近更新 更多