如何在Perl中检查函数参数是字符串还是数组

f45qwnt8  于 2022-11-15  发布在  Perl
关注(0)|答案(3)|浏览(177)

我正在尝试用Perl编写一个自定义的validateParameter函数。我有以下代码,它也可以工作:

sub validateParameter {
    my ($args, $list) = @_;
    
    if ( ref($list) eq "ARRAY" ) {

        foreach my $key (@$list) {
            if ( not defined $args->{$key} ) {
                die "no $key given!";
            }
        }
    } 
    #elsif ( check if string ) {
    #}
}

我想以如下方式调用函数:

validateParameter({ hallo => "Welt", test => "Blup"},  ["hallo", "test"]);

但我也想这样调用我的函数:

validateParameter({ hallo => "Welt", test => "Blup"},  "hallo");

我知道Perl只有以下三种数据类型(标量、散列、数组),但也许有一种聪明的方法可以检查变量是否是字符串。
如何检查给定的参数是否为字符串?

bq9c1y66

bq9c1y661#

更新:不知怎么的,我错过了问题的结尾。仅仅测试ref($list) eq 'ARRAY'在大多数情况下都是可行的,但是为了正确地允许重载对象,您应该尝试解引用参数:

if ( eval { \@$list } ) {
    # it was an array 
}
else {
    # assume it is a string
}

原文回答:
您可以检查有关参数的许多事项:

if ( ! defined $param ) {
    # undefined
}
elsif ( defined Scalar::Util::blessed($param) ) {
    # object
}
elsif ( ref $param ) {
    # reference (return of ref will give the type)
}
elsif ( length do { no warnings "numeric"; $param & '' } ) {
    # number
}
else {
    # string
}

但是所有这些(可能除了定义的检查)都在某种程度上破坏了Perl自动转换为所需类型的目的,并将限制可以传递的内容(例如,需要数字的字符串或dualvar,需要字符串、数字或引用的重载对象,或者绑定变量或魔术变量,如$!)。
您可能还想了解一下Params::Validate的功能。

rlcwz9us

rlcwz9us2#

不要把行为建立在参数的“类型”上,因为实际上并没有这样的事情。如果你使用基于类型的多态性,你会遇到问题,因为Perl值通常有不止一种类型。
例如,

  • "123"产生的标量被存储为字符串,但Perl并不区分它与由123产生的标量,后者没有被存储为字符串。
  • 标量可以同时包含数字和该数字的缓存字符串。(例如my $i = 123; "".$i;
  • 标量可以同时包含数字和字符串(不是数字的字符串化),常见的例子是$!!1
  • 对重载字符串化的对象的引用也是一个有用的字符串。(例如DateTime->now
  • 对数组的引用可能会重载%{}以用作散列引用。对散列的引用可能会重载@{}以用作数组引用。
  • 还有更多。
1zmg4dgp

1zmg4dgp3#

不,没有办法检查标量是否是字符串,因为Perl根据上下文进行隐式类型转换。如果你给予函数一个数字作为第二个参数,并且你在需要字符串的上下文中使用它,它将自动转换为字符串。所以,只要检查ref($list)为空-在这种情况下,$list不是引用,因此它是字符串或数字,您不需要区分这两者。

相关问题