2013-07-26 3 views
4

현재 일부 응용 프로그램 코드를 리팩터링하고 있으며 일부 매개 변수를 서브 루틴에서 제거 할 수 있기를 원합니다.Perl 서브 루틴의 리팩토링 매개 변수 목록

sub do_something { 
    my ($param1, $param2, $param3, $param4) = (@_); 
    .... 
} 

그러나, 리팩토링의 일환으로 나는이 만든 매개 변수 2, 3 중복 : 예를 들어,이 [1] 다음 내가 가진 가정 해 봅시다. 이 메소드 서명을 업데이트하는 것이 쉬운 부분이지만 모든 호출을 업데이트하는 간단한 방법이 있습니까?

나는 그것을하기 위해 맞춤식 grep/sed/perl의 길을 걸어 왔지만, 서브에 대한 호출 중 몇 개는 여러 줄로되어있어, 그것이 주문품이다. 이 특정 리팩터링을 수행하는 데 유용한 도구가 있습니까?

[1] - 실제 매개 변수 또는 서브 루틴 이름이 아니므로, 저는 여러분에게 확신합니다!

+0

을하지만, 메서드에 대한 호출을 안정적으로 찾는 문제 또는 새 인터페이스를 준수하도록 편집하는 문제입니까? –

+0

찾기가 쉽습니다. 모든 인스턴스는 하나의 패키지에 있으며 grep을 사용하여 찾을 수 있습니다. 그것은 편집 문제입니다.나는 호출 매개 변수 목록을 폭발시키고 그것을 다시 결합하는 스크립팅을 할 수는 있지만 이것은 주문품 일 가능성이 높습니다. 이제는 내 자신의 리팩터링 모듈을 작성해야 할 때입니다. – chooban

+0

통화가 여러 줄에 걸쳐 확산되는 경우가 있으므로 그 매개 변수를 생성하기 위해 사소한 계산이 진행되고 있다고 가정합니다. 따라서 매개 변수를 제거하는 것만으로 언급 된 계산 중 일부가 제거 될 수 있기 때문에 많은 호출 사이트에서 수동 정리가 필요할 것으로 예상됩니다. 예를 들어 통화가 중복되기 전의 직선이있을 수 있습니다. – jlh

답변

3

Padre에는 리팩토링을위한 몇 가지 기능이 있지만 원하는 결과를 얻을 수 있는지 여부는 알 수 없습니다.

위치 정보 목록 대신 해시를 허용하도록 인터페이스를 변경하면 향후 변경 사항이 현재보다 적게 수행됩니다.

sub do_something { 
    my (%param) = (@_); 
    ... 
} 

do_something(foo => 23, bar => 42); 
+0

매개 변수에 대한 해시를 사용하는 것은 다소 잘못되었습니다 (이유는 모르겠지만 아마도 현재 내가 수행하지 않기 때문에!)하지만 일단 서브 루틴에 두 개 이상의 매개 변수가 있으면 한 번 갈 수있는 방법이라고 생각합니다. 나는 Padre에게도 좋은 것을 줄 것이다. – chooban

+1

그렇게 느껴서는 안됩니다. 그것은 [모범 사례, 9.4 장 참조] (http://oreilly.com/catalog/perlbp)입니다. – daxim

+0

아하! 내 목록에 추가 할 또 다른 책. 감사! – chooban

0

코드 범위가 거의 100 % 인 테스트 제품군을 사용하는 경우 모든 통화 사이트를 찾을 수 있습니다.

호출 스택의 위치에 대한 인수 감안할 때 caller 내장 반환

  1. 호출자의 패키지 이름
  2. 파일 이름
  3. 행 번호
  4. 완전한 하위 이름
  5. ... 일부 more

이제 호출 위치를 기록하는 코드를 추가 할 수 있습니다. 자동 처리를 위해 결과를 데이터 구조에 넣거나 로그 파일에 보고서를 작성할 수 있습니다. 예 :

sub this_logs { 
    { 
    # seperate scope to not pollute your sub 
    state $log_fh //= do { 
     open my $fh, ">", "record_callsites.log"; # assuming autodie; 
     $fh; 
    }; 
    state $seen = {}; 
    my (undef, undef, undef, $sub) = caller(1); 
    my ($package, $file, $line, ) = caller(0); 
    my $site = $sub ? "$sub()" : "pkg $package"; 
    unless ($seen->{$file}{$line}++) { 
     say {$log_fh} "CALL from $site at $file line $line"; 
    } 
    } 
    my ($param1, $param2) = @_; 
    # etc 
} 

이 가정의 모든 코드는이 로그 파일을 생성 할

this_logs(1, 2, 3);   # direct call 
foo();      # call from same package 
my $sub = "this_" . "logs"; 
baz($sub);     # call by name 
Foo::bar();     # call from different package 
foo();      # duplicate call 

sub foo { 
    return this_logs(5, 6, 7); 
} 
sub baz { 
    shift()->(1, 2, 3); # no strict refs for this, please 
}; 

package Foo; 
sub bar { 
    main::this_logs(); 
} 

했다

그래서 적절한 테스트 스위트를 제공 (파일 이름 -은 STDIN을 의미)

CALL from pkg main at - line 20 
CALL from main::foo() at - line 28 
CALL from main::baz() at - line 31 
CALL from Foo::bar() at - line 3 

, 이 전화를 걸 수없는 전화 사이트를 찾을 수 있습니다.

가 아닌 바보 같은 편집기가있는 경우, 당신은 또한 차례로 각 파일을 열고 올바른 줄에 커서를 위치 스크립트 방출 수 : 내가 바로 가기가 잘 모르는 것 같아요

say "kate -l $line $file"; 
say "vim +$line $file"; 
+0

Funnily 정도로 이것은 테스트 스위트의 내부 함수이므로 100 % 적용 범위가 있음을 희망합니다. ! 이것은 놀랍게도 유용합니다. 가능한 한 빨리 테스트를 해 보겠습니다. – chooban

관련 문제