2010-02-16 2 views
16

최근에는 코드에 Perl::Critic을 더 자주 사용하기로 결정했습니다. Perl에서 7 년 가까이 프로그래밍 한 후에는 오랫동안 대부분의 Perl 베스트 프랙티스에 정착했지만 항상 개선의 여지가 있음을 알고 있습니다. 그래도 나를 괴롭 히고있는 한 가지는 Perl::Critic이 서브 루틴을 위해 @_을 풀어주는 방식을 좋아하지 않는다는 사실입니다. 예를 들어 :Perl :: Critic이 shift를 사용하여 서브 루틴 변수를 채우는 것을 왜 싫어합니까?

sub my_way_to_unpack { 
    my $variable1 = shift @_; 
    my $variable2 = shift @_; 

    my $result = $variable1 + $variable2; 
    return $result; 
} 

이는 양쪽 PerlMonks에 논의되어 나는 항상 그것을 수행하고, 한 방법이며 스택 오버플로, 그 not necessarily evil 중 하나. 위의 코드를 변경

...

sub perl_critics_way_to_unpack { 
    my ($variable1, $variable2) = @_; 

    my $result = $variable1 + $variable2; 
    return $result; 
} 

는 ... 너무 작동하지만, 나는 그것을 열심히 읽고 찾을 수 있습니다. 나는 또한 Damian Conway의 저서 Perl Best Practices을 읽었으며 Perl::Critic이 의미하는대로 @_을 직접 사용하는 것을 피하기 위해 선호하는 포장 풀기 방법이 자신의 제안에 어떻게 미치는지 이해하지 못합니다. 나는 항상 콘웨이 같은 불결함에 대해 이야기하고 있다는 인상을 받고했습니다

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

위의 예 읽기 나쁜 어렵다, 나는 지금까지 생산 코드의 조각에 서면 생각하지 않을 것입니다.

간략히 말하자면, Perl::Critic은 내가 선호하는 방식을 왜 잘못 생각합니까? 나는 교대로 짐을 풀어 가증스러운 범죄를 저지르고 있는가?

내 생각에 다른 사람이 Perl::Critic 메인테이너와 함께 기상해야한다고 생각하십니까?

+2

Perl :: Critic은 변수가 지정되지 않은 경우'@ _ '에서 작동하는'shift '와 같은 "magic"을 사용하기 때문에 Perl :: Critic이 마음에 들지 않습니다. 그것은 어떤 Perl :: Critic 규칙이 이것을 바꾸고 싶어하는지 알면 도움이 될 것입니다. – Powerlord

+4

제쳐두고, 목록 형식의 할당을 사용하면 Komodo Edit/IDE에서 서브 루틴에 대한 인수를 알 수 있습니다. –

+1

Brad에게 감사드립니다. 나는 그것을 깨닫지 못했습니다. 나는 오래 된 ViM 사용자이기 때문에 대개 코모도 편집이 내 앞에 놓고있는 것을 무시하지만, 나는 항상 그것이 어떻게 작동하는지 궁금해했습니다. – Weegee

답변

11

간단한 대답은 Perl :: Critic이 여기 PBP를 따르지 않는다는 것입니다. 책에서는 교대 관용구가 수용 가능할뿐만 아니라 어떤 경우에는 실제로는 을 선호한다고 명시되어 있습니다.

+0

오늘 밤 집에 도착하면 책을 열고 섹션을 다시 읽어야 할 것입니다.하지만 잠시 동안은 읽었을 것입니다.하지만 당신이 옳을 수도 있습니다. – Weegee

+0

네, 이제 확인할 수 있습니다. – Weegee

8

Perl Best Practices의 많은 내용은 가장 좋아 보이는 것 또는 가장 쉽게 작업 할 수있는 것에 대한 한 사람의 의견이며, 다른 방법을 사용하더라도 문제가되지 않는다는 점을 기억해야합니다. Damian은 책의 소개 텍스트에서 많은 것을 말합니다. 그것은 그것이 이라고 말하지 않습니다.처럼 - 절대적으로 필수적인 많은 것들이 있습니다 : 예를 들어 strict을 사용하십시오.

코드를 작성할 때 자신의 모범 사례가 무엇인지 스스로 결정해야하며 PBP를 사용하는 것이 가장 좋은 출발점입니다. 그런 다음 자신의 표준을 준수하십시오.

나는 PBP의 대부분을 따라하려고하지만 Damian은 나의 서브 루틴 - 인수 shift과 내 unless es를 감기에 걸렸습니다.

크리틱에서는 적용 할 정책을 선택할 수 있으며 아직 존재하지 않는 경우 자신의 정책을 만들 수도 있습니다.

+1

그건 좋은 지적이고 나는 그것에 동의하지만, 내 관심은 Perl :: Critic이 기본 상태에서 서브 루틴 인수 이동을 사용하는 것이 좋지 않다고 말하면 옳은지 여부입니다. – Weegee

9

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 `(@_)'. 
+1

그렇기 때문에 Perl :: Critic이 "Always unpack @_"대소 문자를 유효하게 검사하는지 여부가 궁금합니다. – Weegee

+1

+1 for '--verbose 11' – sebthebert

2

경우에 따라 Perl :: Critic은 PBP 지침을 정확하게 시행 할 수 없으므로 Conway 지침의 정신에 맞게 근사치를 적용 할 수 있습니다. PBP를 잘못 해석했거나 잘못 적용했을 가능성이 있습니다. 바르게 냄새가 나지 않는 것을 발견하면 [email protected]에 버그 보고서를 보내 주시고 바로 살펴 보겠습니다.

감사합니다,

-Jeff

+0

여기에 게시 해 주셔서 감사합니다. Jeff. 나는 나의 걱정에 대해 내일 이메일을 [email protected] 이메일 계정으로 보낼 것이다. 나는 Conway의 책에서 Section 9.3을 다시 읽었으며 "Subarutine의 첫 번째 단락으로 일련의 개별 교대 호출을 사용할 수 있습니다"라고 명시되어 있습니다. – Weegee

0

내가 정말 필요하지 않은 경우 당신이 일반적으로 변화를 방지해야한다고 생각!

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

이 코드에서 뭔가를 변화 시작하면, 거기에 당신이 accidantially 손떨림의 순서를 변경 또는 어쩌면 하나를 건너 뛸 수있는 좋은 기회이며, 모든 southway 간다 :

그냥이 같은 코드로 실행 . 게다가 아래의 몇 줄은 다른 어딘가에있을 수 있기 때문에 하위의 모든 매개 변수를 실제로 볼 수 없기 때문에 읽기가 어렵습니다 ... 중간에 Regexes를 사용하면 $ _의 내용을 바꿀 수 있습니다. 이상한 일들이 일어나기 시작합니다 ...

내 (...) = @_를 풀면 바로 직접 (...) 부분을 복사하여 붙여 넣기 할 수 있습니다. 좋은 서명 :) 당신은 심지어 같은 변수 이름을 미리 사용할 수 있으며, 어떤 것을 변경할 필요가 없습니다!

나는 시프트가 목록의 길이가 동적이고 목록의 요소를 한 번에 하나씩 처리하려고하거나 첫 번째 요소없이 명시 적으로 목록을 필요로하는 목록 작업을 의미한다고 생각합니다. 그러나 전체 목록을 x 매개 변수에 할당하려는 경우 코드에서 my (...) = @_; 아무도 궁금해 할 필요가 없다.

관련 문제