如何检查函数参数是否是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
)
对数组的引用可能会过载 %{}
以用作散列引用。对散列的引用可能会过载 @{}
以用作数组引用。
还有更多。
我正在尝试使用 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
)对数组的引用可能会过载
%{}
以用作散列引用。对散列的引用可能会过载@{}
以用作数组引用。还有更多。