2017-05-29 64 views
0

我试图用我的自定义函数validateParameter函数与perl。 实际我有下面的代码也可以工作:如何检查函数参数是否是perl中的字符串

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只有以下三种数据类型(标量,哈希,数组)。但也许有一个聪明的方法来检查一个变量是否是一个字符串。

感谢大家。

+0

你的意思是“字符串”而不是“数字”?或“字符串”,而不是“arrayref/hashref/...”?然后['ref'](http://perldoc.perl.org/functions/ref.html)是要走的路(如你已经做的那样)。它为简单的非ref标量返回一个空字符串(比如'$ list')。 – PerlDuck

+0

哦,好吧,我的错:D。这篇文章完成了。谢谢@PerlDuck –

回答

1

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

+1

那么,有[Scalar :: Util :: looks_like_number](http://perldoc.perl.org/Scalar/Util.html#looks_like_number)(核心模块)来检测数字,但我不认为这是OP之后的事情。 – PerlDuck

+0

注意'ref($ list)'将返回一个字符串超载的对象。这意味着'我的$ url = URI-> new('http://stackoverflow.com/'); validateParameter({hallo =>“Welt”,test =>“Blup”},$ url);即使'$ url'可以作为一个字符串使用''也会失败。 – ikegami

3

更新:我不知何故错过了问题的结尾。只是测试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其中NU mber是想要的,或者需要字符串,数字或引用的重载对象,或绑定变量或魔术变量,如$!)。

您可能还想看看Params::Validate可以做什么。

+0

注意:如果它是'undef','\ @ $ list'会自动生成'$ list',所以如果这是一个有效的输入,那么先处理'undef'。 – ikegami

+0

@ikegami我猜测undef会更像一个空数组而不是undef“string” – ysth

1

不要基于“参数类型”的行为,因为确实没有这样的事情。如果使用基于类型的多态性,则会遇到问题,因为Perl值通常具有多种类型。

例如,

  • 通过"123"产生的标量存储为作为字符串,但Perl不从由123产生的标量,它没有被存储为一个字符串区分开来。

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

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

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

  • 对数组的引用可能会将%{}重载为可用作散列引用。对散列的引用可能会将@{}重载为可用作数组引用。

  • 等等。

相关问题