代码之家  ›  专栏  ›  技术社区  ›  Weegee

为什么Perl::Critic不喜欢使用shift填充子例程变量?

  •  16
  • Weegee  · 技术社区  · 16 年前

    Perl::Critic 更多的是我的代码。在用Perl编程近7年之后,我已经习惯了大部分Perl最佳实践很长一段时间了,但我知道总有改进的余地。但有一件事一直困扰着我 不喜欢我为子程序解包的方式。例如:

    sub my_way_to_unpack {
        my $variable1 = shift @_;
        my $variable2 = shift @_;
    
        my $result = $variable1 + $variable2;
        return $result;
    }
    

    not necessarily evil

    正在将上面的代码段更改为。。。

    sub perl_critics_way_to_unpack {
        my ($variable1, $variable2) = @_;
    
        my $result = $variable1 + $variable2;
        return $result;
    }
    

    ……也很管用,但我觉得很难读。我也读过达米安·康威的书 Perl Best Practices 我真的不明白我喜欢的解包方法是如何在他的建议下避免使用 @_ 直接,作为 暗示。我一直觉得康威在谈论一些不好的事情,比如:

    sub not_unpacking {
        my $result = $_[0] + $_[1];
        return $result;
    }
    

    上面的例子不好,很难阅读,我永远不会考虑写在一个生产代码中。

    Perl::评论家

    除了我自己,其他人会不会认为这是应该被带大的 Perl::评论家 维修人员?

    5 回复  |  直到 9 年前
        1
  •  11
  •   PBP reader    16 年前

    简单的答案是Perl::Critic在这里没有遵循PBP。这个 这本书明确指出,移位习语不仅是可以接受的,而且是可以接受的 实际上在某些情况下是首选的。

        2
  •  9
  •   mob    16 年前

    跑步 perlcritic 具有 --verbose 11 解释政策。不过,这两种解释似乎都不适用于你。

    Always unpack @_ first at line 1, near 
    'sub xxx{ my $aaa= shift; my ($bbb,$ccc) = @_;}'.
      Subroutines::RequireArgUnpacking (Severity: 4)
        Subroutines that use `@_' directly instead of unpacking the arguments to
        local variables first have two major problems. First, they are very hard
        to read. If you're going to refer to your variables by number instead of
        by name, you may as well be writing assembler code! Second, `@_'
        contains aliases to the original variables! If you modify the contents
        of a `@_' entry, then you are modifying the variable outside of your
        subroutine. For example:
    
           sub print_local_var_plus_one {
               my ($var) = @_;
               print ++$var;
           }
           sub print_var_plus_one {
               print ++$_[0];
           }
    
           my $x = 2;
           print_local_var_plus_one($x); # prints "3", $x is still 2
           print_var_plus_one($x);       # prints "3", $x is now 3 !
           print $x;                     # prints "3"
    
        This is spooky action-at-a-distance and is very hard to debug if it's
        not intentional and well-documented (like `chop' or `chomp').
    
        An exception is made for the usual delegation idiom
        `$object->SUPER::something( @_ )'. Only `SUPER::' and `NEXT::' are
        recognized (though this is configurable) and the argument list for the
        delegate must consist only of `( @_ )'.
    
        3
  •  8
  •   brian d foy    16 年前

    Perl Best Practices 全部的 就像这样--里面有很多东西是绝对必要的:使用 strict 例如。

    我试着遵循PBP中的大部分内容,但是Damian可以有我的子程序参数 shift s和我的 unless 当他从我冰冷死寂的指尖上撬开它们的时候。

    至于Critic,您可以选择要实施的策略,甚至可以创建自己的策略(如果它们还不存在)。

        4
  •  3
  •   Jeffrey Thalhammer    16 年前

    -杰夫

        5
  •  0
  •   Falco    12 年前

    我认为你应该避免换班,如果不是真的有必要的话!

    刚遇到这样的代码:

    sub way {
      my $file = shift;
      if (!$file) {
        $file = 'newfile';
      }
      my $target = shift;
      my $options = shift;
    }
    

    使用unpacking my(…)=@@的一个直接好处是,您只需复制(…)部分并将其粘贴到调用该方法的位置,并且有一个很好的签名:)您甚至可以预先使用相同的变量名,而不必更改任何内容!

    我认为shift意味着列表操作,其中列表的长度是动态的,您希望一次处理一个元素,或者显式地需要一个没有第一个元素的列表。但是如果您只想将整个列表赋给x参数,那么代码应该用my(…)=@;没人会怀疑。