1

给定示例代码:

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

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

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

输出:

{预期为空白}
标量
数组
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; }
4

2 回答 2

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::Utilreftype实际上获取 ref 类型。ref可以返回类名而不是引用类型。)

请注意,根据存储类型区分值在 Perl 中是一个糟糕的设计。它必然是错误的,因为它破坏了重载的对象。

于 2012-12-05T20:16:24.677 回答
1

给定一个 pragma 的范围

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

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

于 2012-12-05T20:54:01.683 回答