如何在Perl中检查几个变量是否为空

chi*_*org 4 variables perl

我有一个Perl脚本,在脚本可以继续之前必须初始化变量.if 我检查每个变量的冗长陈述是显而易见的选择.但也许有更优雅或简洁的方法来检查几个变量.

编辑: 我不需要检查"已定义",它们总是用空字符串定义,我需要检查所有都是非空的.

例:

my ($a, $b, $c) = ("", "", "");

# If-clauses for setting the variables here

if( !$a || !$b || !$c) {
  print "Init failed\n";
}
Run Code Online (Sandbox Code Playgroud)

DVK*_*DVK 8

"初始化"是什么意思?有没有"undef"的值?

对于少量的值,直接检查是恕我直言,最易读/可维护.

if (!$var1 || !$var2 || !$var3) {
    print "ERROR: Some are not defined!"; 
}
Run Code Online (Sandbox Code Playgroud)

顺便说一句,检查!$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!"; 
}
Run Code Online (Sandbox Code Playgroud)

如果有太多的值来检查上面的内容变得难以阅读(尽管在第二个示例中进行了每行检查,但实际上并没有发生),或者如果值存储在数组中,则可以使用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!"; 
}
Run Code Online (Sandbox Code Playgroud)

如果您必须知道未定义值的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; 
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为如果你发现自己明确写了`$ _`,你可能会在Perl中做一些次优的事情.我特别讨厌`$ _ =〜/ foo /`.我经常写`grep {length} @ list`,`map {hex} @ list`,或`for(@list){s/foo/bar /}`.即使`键%h == grep {定义$ h {$ _}}键%h`也可以是`值%h == grep {defined} values%h`.一个闭包表达式很短,足以在我的头脑中为`grep`,`map`,`first`,`all`和c保存`$ _`的含义.具有混合访问"$ this"和"$ that"的较长代码值得为抽象命名:`$ _`并不适用于此. (3认同)

zou*_*oul 8

use List::MoreUtils 'all';
say 'Yes' if (all { defined } $var1, $var2, $var3);
Run Code Online (Sandbox Code Playgroud)

  • 关于不断转向模块的事情,尤其是非标准的模块,我深感矛盾.一方面,我不希望人们严重地重复轮子,但另一方面,我希望他们能够熟练掌握基本的Perl功能,这些功能已经存在于核心语言本身的运作方式中. (6认同)

Sin*_*nür 8

我假设表示空字符串,而不仅仅是任何错误值.也就是说,如果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;
}
Run Code Online (Sandbox Code Playgroud)

现在,这作为验证是没有用的,因为,如果发生这种情况,您很可能想知道哪个变量未正确初始化.

将配置参数保存在哈希中可以更好地服务,这样您就可以轻松检查哪些参数已正确初始化.

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;
}
Run Code Online (Sandbox Code Playgroud)

或者,如果要列出所有未正确初始化的内容:

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 );
}
Run Code Online (Sandbox Code Playgroud)


Eug*_*ash 7

use List::Util 'first';

if (defined first { $_ ne "" } $a, $b, $c) {
    warn "empty";
}    
Run Code Online (Sandbox Code Playgroud)

  • 通过*empty*,OP可能意味着*空字符串*,而不是*false*.在Perl中检查的标准方法是`length`.另外,不要使用`$ a`和`$ b`,因为它们是`sort`使用的包变量. (2认同)