Perl:一举检查一下hashref的ref的正确方法?

时间:2012-12-05 19:57:38

标签: perl ref

给出示例代码:

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

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

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

输出:

  

{预计空白}
  标量
  ARRAY
  REF


我想测试的是检查传递的是标量还是数组的最佳方法。类似的东西:

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; }

2 个答案:

答案 0 :(得分:3)

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

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中设计较差。它必然是错误的,因为它打破了重载的对象。

答案 1 :(得分:1)

考虑到

范围内的实用主义
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}" }
  }
}

输出:

plain scalar 'test'
array, length=1

您的问题很抽象,但随着您对自己想做的事情的了解越来越多,我们可以针对您的具体情况提供更具体,更有帮助的建议。