给出示例代码:
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; }
答案 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
您的问题很抽象,但随着您对自己想做的事情的了解越来越多,我们可以针对您的具体情况提供更具体,更有帮助的建议。