如何检查函数参数是否是perl中的字符串

How to check if a function parameter is a string in perl

我正在尝试使用 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");

我如何检查给定的 arg 是否为 "string"?

我知道 perl 只有以下三种数据类型(标量、散列、数组)。但也许有一种聪明的方法来检查一个变量是否是一个字符串。

谢谢大家

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

更新:我不知何故错过了问题的结尾。大多数时候只测试 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 可以做什么。

不要将行为建立在 "type" 参数上,因为确实没有这样的东西。如果您使用基于类型的多态性,您将 运行 遇到问题,因为 Perl 值通常有不止一种类型。

例如,

  • "123" 生成的标量存储为字符串,但 Perl 不将其与 123 生成的未存储为字符串的标量区分开来.

  • 标量可以包含数字和该数字的缓存字符串化。 (例如 my $i = 123; "".$i;

  • 标量可以包含数字和字符串(这不是数字的字符串化)。这些常见的例子是 $!!1.

  • 对重载字符串化的对象的引用也是一个有用的字符串。 (例如 DateTime->now

  • 对数组的引用可能会过载 %{} 以用作散列引用。对散列的引用可能会过载 @{} 以用作数组引用。

  • 还有更多。