我有一个Perl脚本,在脚本可以继续之前必须初始化变量。我检查每个变量的冗长if
语句是显而易见的选择。但也许有更优雅或简洁的方法来检查几个变量。
修改 我不需要检查“已定义”,它们总是用空字符串定义,我需要检查所有都是非空的。
示例:
my ($a, $b, $c) = ("", "", "");
# If-clauses for setting the variables here
if( !$a || !$b || !$c) {
print "Init failed\n";
}
答案 0 :(得分:8)
“初始化”是什么意思?有不是“undef”的值吗?
对于少量的值,如果检查是直截了当的恕我直言,最易读/可维护。
if (!$var1 || !$var2 || !$var3) {
print "ERROR: Some are not defined!";
}
顺便说一句,检查!$var
是一个可能的错误,因为在Perl中“0”为假,因此初始化为“0”的字符串将无法通过此检查。使用$var eq ""
或者更好的是,为> 3值
提供空间if (!$var1 # Use this if your values are guarantee not to be "0"
|| $var2 eq "" # This is a LOT better since !$var fails on "0" value
|| $var3 eq "") {
print "ERROR: Some are not defined!";
}
如果有太多的值要检查以上内容变得难以阅读(尽管如第二个示例中的每行检查,但实际上并未发生),或者如果值存储在一个数组,你可以使用grep抽象出检查:
# We use "length" check instead of "$_ eq ''" as per tchrist's comment below
if (grep { length } ($var1, $var2, $var3, $var4, $var5, @more_args) ) {
print "ERROR: Some are not defined!";
}
如果您必须知道未定义值的WHICH,您可以使用for循环(左侧作为读者的明显练习)或地图技巧:
my $i = -1; # we will be pre-incrementing
if (my @undefined_indexes = map { $i++; $_ ? () : $i }
($var1, $var2, $var3, $var4, $var5, @more_args) ) {
print "ERROR: Value # $_ not defined!\n" foreach @undefined_indexes;
}
答案 1 :(得分:8)
use List::MoreUtils 'all';
say 'Yes' if (all { defined } $var1, $var2, $var3);
答案 2 :(得分:8)
我假设 empty 表示空字符串,而不仅仅是任何false值。也就是说,如果0
或"0"
在初始化后始终是有效值,则当前接受的答案会给您错误的结果:
use strict; use warnings;
my ($x, $y, $z) = ('0') x 3;
# my ($x, $y, $z) = ('') x 3;
for my $var ($x, $y, $z) {
die "Not properly initialized\n" unless defined($var) and length $var;
}
现在,这在验证方面毫无用处,因为如果发生这种情况,您很可能想知道哪个变量未正确初始化。
通过将配置参数保存在哈希中可以更好地服务,这样您就可以轻松检查哪些参数已正确初始化。
use strict; use warnings;
my %params = (
x => 0,
y => '',
z => undef,
);
while ( my ($k, $v) = each %params ) {
validate_nonempty($v)
or die "'$k' was not properly initialized\n";
}
sub validate_nonempty {
my ($v) = @_;
defined($v) and length $v;
}
或者,如果您想列出所有未正确初始化的内容:
my @invalid = grep is_not_initialized($params{$_}), keys %params;
die "Not properly initialized: @invalid\n" if @invalid;
sub is_not_initialized {
my ($v) = @_;
not ( defined($v) and length $v );
}
答案 3 :(得分:7)
use List::Util 'first';
if (defined first { $_ ne "" } $a, $b, $c) {
warn "empty";
}
答案 4 :(得分:3)
您的方式易读且容易理解,这意味着它易于维护。使用de Morgan's laws重新声明布尔值:
if (not($a and $b and $c)) {
warn(qq(Not all variables are initialized!))
}
这样,你不会在每个变量前面加上而不是前缀,并且它不会影响可读性。您可以使用List::Util
或List::MoreUtils
,但它们并没有真正增加易读性。
正如SinanÜnür所说,如果将变量放在散列中,您可以解析散列,然后列出哪些变量未初始化。如果有很多这些变量,这可能是最好的,并且列表会不断变化。
foreach my $variable qw(a b c d e f g h i j) {
if (not $param{$variable}) {
warn qq(You didn't define $variable\n);
}
}
您可以使用Getopts::Long
将参数值放在哈希中而不是单独的变量中。此外,最新版本的Getopts::Long
现在可以在任何阵列上运行,而不仅仅是@ARGV
。