代码之家  ›  专栏  ›  技术社区  ›  Radu Maris

编写代码的最佳方法是使用严格的

  •  2
  • Radu Maris  · 技术社区  · 14 年前

    检查提供给子例程的参数以进行严格编译的最佳方法是什么(我的解决方案可行,但有更好的方法吗?)

    Use of uninitialized value in string eq at ../lib/cgilibtest.pl line 1510
    Use of uninitialized value in concatenation (.) or string at ../lib/cgilibtest.pl line 1511.
    

    它们是由这样编写的子程序生成的:

    #!/usr/bin/perl -w
    sub example()
    {
        my $var1 = shift @_;
        my $var2 = shift @_;
        my $var3 = shift @_;
        if($var2 eq ""){var2 = "something";} # this line generates the first type of error beacause $var2 is not defined
        return "var1 = ".$var1.", var2 = ".$var2.", var3 = ".$var3; # this line generates the second type of error, beacause $var3 is not defined
    }
    print "Content-type: text/html\n\n";
    $someVar = &example("firstVar");
    print $someVar;
    

    我的解决方案是使用三元运算符并将它们写成:

    #!/usr/bin/perl -w
    use strict;
    
    sub example()
    {
        my $var1 = ($_[0])?$_[0]:"";
        my $var2 = ($_[1])?$_[1]:"something";
        my $var3 = ($_[2])?$_[2]:"";
        return "var1 = ".$var1.", var2 = ".$var2.", var3 = ".$var3;
    }
    print "Content-type: text/html\n\n";
    my $someVar = &example("firstVar");
    print $someVar;
    

    在PHP中我使用 function example ($var1, $var2 = null, $var3 = null){...}

    另外,如果有人知道一本关于“用perl编写严格的代码”的教程或手册,请留下一个链接。

    3 回复  |  直到 14 年前
        1
  •  3
  •   Axeman maxelost    14 年前

    warnings ,不是 . 虽然它通常与严格的。

    my $var1 = shift || '';
    

    '' 不是未初始化的,因此不会得到警告。Ternaries也是一种很好的方法,我在我的产品代码中已经充分使用了它们。

    当然,还有另外一个问题。如果你看看上面的代码,我期望什么?我期待着 $var1 可能没有传递任何数据。如果是这样的话,我仍然想把它串起来——而且还有 足够地

    # don't bug me about uninitialized stringed values
    # just concatenate them
    no warnings 'uninitialized'; 
    return "var1 = ".$var1.", var2 = ".$var2.", var3 = ".$var3; 
    

    这相当于用一堆变量来实现这一点:

    my $var = shift || '';
    

    惊喜

    既然你的sub很简单,上面的代码就可以了。但是您可能希望在将来做更多的工作,因此我建议使用以下构造来隔离那些我们可以处理未初始化值的部分,以及您不希望被发现不知道的部分。

    {   no warnings 'uninitialized';
        $string = ...;
    }
    $obj_that_should_be_defined->do_something_objecty( $string );
    

    do 块对此也很有用。

    $obj_that_should_be_defined->do_something_objecty( 
        do { no warnings 'uninitialized'; sprintf( ... ); }
    );
    

    map . 如果您只想处理undefs,下面的方法就可以了。

    $object->method( map { defined() ? $_ : '' } @anon_args );  
    
    • 如果 在那种情况下,你在乎他们是不是 undef

    现在,很多时候人们检查未定义的变量只是为了发出嘎吱声。因为Perl的消息已经变得更好了,也许将来它们还可以改进。也许没有必要特别地呱呱叫。

    my $feldman = Feldman->new( qw<here is some data for you> )
        or die 'Could not create Feldman!'
        ;
    $feldman->dont_just_sit_there_do_something();
    

    但是没有明确的 or die ,如果 $feldman $费尔德曼 是未定义的,那么您没有创建它,您只需要从未定义到错误消息再进行一级推断。都没告诉我们 为什么? 对象没有被创建,只是它没有被创建(构造器至少应该对它没有的东西吹毛求疵。)

        2
  •  2
  •   Toto    14 年前
    sub example {
      my $var1 = shift || '';
      my $var2 = shift || 'something';
      my $var3 = shift || '';
    
      return "var1 = ".$var1.", var2 = ".$var2.", var3 = ".$var3;
    }
    
        3
  •  1
  •   FMc TLP    14 年前

    我赞成这个建议 Perl最佳实践

    对于所有采用相同默认值的位置参数,我经常这样做:

    sub example {
        my ($var1, $var2, $var3) = map { defined() ? $_ : '' } @_;
    }
    

    sub example {
        my %DEFAULTS = ( foo => 0, bar => '', fubb => 'blah' );
    
        # When the hashes are merged, user-supplied arguments
        # will trump the defaults.
        my %args = (%DEFAULTS, @_);
    }
    
    example(foo => 123);
    

    如果我没记错的话, 多溴联苯 讨论合并哈希的技巧,这在许多上下文中都很有用。