如何检查函数参数是否是perl

时间:2017-05-29 13:29:15

标签: function perl arguments subroutine

我正在尝试使用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是否为“字符串”?

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

感谢大家。

3 个答案:

答案 0 :(得分:4)

更新:我不知何故错过了问题的结束。只是测试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自动转换为所需类型的目的,并限制可传递的内容(例如,字符串或双变量,其中一个数字是想要的,或者需要字符串,数字或引用的重载对象,或者绑定变量或魔术变量,例如$!)。

您可能还想查看Params::Validate可以执行的操作。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

不要基于"类型"争论因为真的没有这样的事情。如果使用类型基多态,则会遇到问题,因为Perl值通常有多种类型。

例如,

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

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

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

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

  • 对数组的引用可能会使%{}重载为可用作哈希引用。对哈希的引用可能会使@{}重载为可用作数组引用。

  • 等等。