2013-08-31 8 views
1

typeglob의 첫 번째 예제에는 두 번째 예제와 비교하여 단점이 있습니까?typeglobs를 사용하여 함수 상속

package Some::Module::Win32; 
use strict; 
use 5.10.0; 

use Exporter 'import'; 
our @EXPORT_OK = qw(public); 

use Some::Module; 

*_func_one = \&Some::Module::_func_one; 
*_func_two = \&Some::Module::_func_two; 
*_func_three = \&Some::Module::_func_three; 

sub public { 
    my $s = _func_one(); 
    for my $i (0 .. $s) { 
     say _func_two($i); 
    } 
    say _func_three($s); 
} 

1; 

package Some::Module::Win32; 
use strict; 
use 5.10.0; 

use Exporter 'import'; 
our @EXPORT_OK = qw(public); 

use Some::Module; 

sub public { 
    my $s = Some::Module::_func_one(); 
    for my $i (0 .. $s) { 
     say Some::Module::_func_two($i); 
    } 
    say Some::Module::_func_three($s); 
} 

1; 

답변

3

첫 번째 예의 종류의 방법 Exporter 작품을 보여줍니다 typeglobs을 할당하여. 그러나 중요한 차이가 있습니다 : 함수를 가져올 때. 이것은 서브 루틴이 프로토 타입을 가지고있을 때 주로 중요합니다. 프로토 타입은 구문 분석 중에 으로 알려 져야하므로 BEGIN 단계에 알려야합니다. use - 일반적으로 import을 사용한 패키지에서 - BEGIN 단계에서 처리됩니다.

당신은 또한 당신의 첫 번째 예에서는 코드의 사용자가이 반면 Some::Module::Win32::_func_one()가 (2 예에서 가능하지 않다 지금 할 수 있음을 깨달아야한다 Some::Module 수출 _func_one하지 않는 한. 여기

는의 기능을 가져 버전입니다 올바른 단계 :

package Some::Module::Win32; 
use strict; 
use 5.10.1; # because `parent` comes with 10.1 

use parent 'Exporter'; # optimal way to inherit the `import`. 
our @EXPORT_OK = qw(public); 

use Some::Module; 

BEGIN { 
    *_func_one = \&Some::Module::_func_one; 
    *_func_two = \&Some::Module::_func_two; 
    *_func_three = \&Some::Module::_func_three; 
} 

sub public { 
    my $s = _func_one(); 
    for my $i (0 .. $s) { 
     say _func_two($i); 
    } 
    say _func_three($s); 
} 

1; 

그리고 당신은, 당신은 심볼 테이블에서 외국 수입을 제거하기 위해 namespace::autoclean 같은 모듈을 사용하려는 경우 그들은 더 이상 당신이 필요로되면

.

또 다른 전략은 어휘 변수에 코드 설명을 넣는 것입니다. 그러나, 구문은 조금 추한이고, 어떤 프로토 타입은 완전히 무시 같습니다

package Some::Module::Win32; 
use strict; 
use 5.10.1; 

use parent 'Exporter'; 
our @EXPORT_OK = qw(public); 

use Some::Module; 

my $func_one = \&Some::Module::_func_one; 
my $func_two = \&Some::Module::_func_two; 
my $func_three = \&Some::Module::_func_three; 

sub public { 
    my $s = $func_one->(); 
    for my $i (0 .. $s) { 
     say $func_two->($i); 
    } 
    say $func_three->($s); 
} 

1; 

이것은 심볼 테이블에 접촉하지 않기 때문에 매우 "깨끗한"솔루션 간주 될 수 있습니다.

두 번째 버전은 좀 더 자세한 정보 일 수 있지만 매우 명확한 이점이있어 독자 나 유지 관리자가 코드를 더 쉽게 이해할 수 있습니다. 제가 자주 사용하는 해결책입니다.

  • 프로토 타입이 제대로 작동
  • 가독성 (함수의 전체 이름은 Marpa::R2::Inner::Scanless::G::SYMBOL_IDS_BY_EVENT_NAME_AND_TYPE처럼 미친 듯이 긴 경우를 제외하고)
  • 모호 추가
  • 네임 스페이스 오염
+0

분명히 아무것도 기술, 그러나 읽을 수있는 +1. 당신이 정말로 필요할 때 영리한 코드를 보관하십시오. –