2009-04-08 4 views
18

내가 한 번에 하나씩 나열 할 필요없이 내 네임 스페이스에있는 모든 잠수함을 노출하고 싶은 : 기존 코드에 변화의 무리를 필요로 정규화 된 이름을 사용Perl 패키지의 모든 서브를 어떻게 내 보낼 수 있습니까?

@EXPORT = qw(firstsub secondsub third sub etc); 

그래서 차라리 그렇게 할 것입니다.

@EXPORT_ALL이 있습니까?

설명서에 잘못된 생각이 들지만 어쨌든 그것을하고 싶습니다. 아니면 적어도 어떻게하는지 알고 싶습니다.

Jon의 답변 : 빠른 리팩토링을 위해 현재 잔뜩 잠겨있는 코드를 기존 스크립트 (최소한 현재 사용되고 자주 반복되는)에 최소한의 번거 로움과 코드 변경만으로 이동시켜야합니다.

또한 대부분, 나는 단지 호기심이 많았습니다. (즉 수출뿐만 아니라있을 수 있습니다 것처럼 보였다 때문에 그 표준 기능,하지만 같은 다소 놀랍게도 지금까지이되지 않습니다 응답에 따라)

+0

왜 우리가 * 왜 * 당신이 이것을하고 싶은지 알려 주실 수 있다면.그냥 발 차기? –

+0

좋아, 몇 가지 이유를 추가했습니다. –

답변

23

전혀 내보내지 말고 라이브러리에 패키지 이름을 선언하지 마십시오. require으로 파일을로드하면 모든 것이 현재 패키지에 있습니다. 쉬워요.

+0

우수 답변! –

+0

Doh! 나는 그 솔루션에 대해 생각하지 않고 그 모든 것을 탭 댄스했다. (그러나 모듈이 자신의 네임 스페이스를 갖게 될 것이라는 기대를 깨뜨리는 것은 놀랄 수 있습니다.) –

+3

파일을 어떻게 "로드"해야합니까? –

2

당신은 항상 완전 지정의 형태로 서브 루틴을 호출 할 수 있습니다

MyModule::firstsub(); 

내부적으로 작성한 모듈의 경우이 규칙이 상당히 잘 작동합니다. 좀 더 타이핑하는 것이지만 더 나은 문서화가되는 경향이 있습니다.

수행하려는 작업에 대한 자세한 내용은 perldoc perlmod을 참조하십시오.

더 일반적으로 Exporter의 코드를보고 glob 별칭을 사용하는 방법을 확인할 수 있습니다. 또는 모듈의 네임 스페이스를 검사하고 각 서브 루틴을 내보낼 수 있습니다. (나는 생각하지 않는다

package main; 
sub firstsub() { ... } 

: (나는 순간에 그 작업을 수행하는 방법을 검색 상관 없어,하지만 펄이 매우 쉽게한다.) 또는 당신은 단지 main 패키지에 서브 루틴을 스틱 수 그게 좋은 생각이지만, 당신이 성취하고자하는 것을 잘 알고 있습니다.)

제공된 당신은 당신이하고있는 일을 알고 당신의 생각을 피하려고하지 않고 있습니다. 외부 세계와의 인터페이스.

+0

예, 저도 알고 있습니다 만, 모든 하위에 대해 MyModule ::을 말할 필요가없는 것은 어떨까요? 내가 모두 내보내기를 찾고 있습니까? –

+0

@Ville M : 말을하지 않으면 다른 사람이 알고있는 것을 알기가 어렵습니다. ;-) –

+0

숲에 떨어지는 소리와 나무에 관한 것이 어쨌든, 당신의 도움에 감사합니다. –

3

경고, 다음과 같은 코드가 수출 모두 같은 생각과 같은 나쁜 :

여기
package Expo; 

use base "Exporter"; 

seek DATA, 0, 0; #move DATA back to package 

#read this file looking for sub names 
our @EXPORT = map { /^sub\s+([^({\s]+)/ ? $1 :() } <DATA>; 

my $sub = sub {}; #make sure anon funcs aren't grabbed 

sub foo($) { 
    print shift, "\n"; 
} 

sub bar ($) { 
    print shift, "\n"; 
} 

sub baz{ 
    print shift,"\n"; 
} 

sub quux { 
    print shift,"\n"; 
} 

1; 

__DATA__ 

인 모듈을 사용하는 일부 코드 : 여기

#!/usr/bin/perl 

use strict; 
use warnings; 

use Expo; 

print map { "[$_]\n" } @Expo::EXPORT; 

foo("foo"); 
bar("bar"); 
baz("baz"); 
quux("quux"); 

을 그리고 그 출력은 다음과 같습니다

[foo] 
[bar] 
[baz] 
[quux] 
foo 
bar 
baz 
quux 
+0

정확히 내가 기대했던 것, 수출업자의 표준 방법은 아닙니다. 그러나 이것은 분명히 필요한 것입니다. 덕분에 많이 –

+1

난 그냥 기호 테이블을 통과하고 정의 된 코드 항목을 찾으십시오 것 같아요. 정규 표현식이 실패 할 수있는 방법은 너무 많습니다. –

+0

"심볼 테이블을 걷는 방법"에 대해 자세히 설명해 주시겠습니까? –

10

하지 마십시오. 그러나 정말로 원하는 경우 ... 심볼 테이블을 걷고 모든 명명 된 서브 루틴을 내보내는 사용자 정의 import을 작성하십시오.

# Export all subs in package. Not for use in production code! 
sub import { 
    no strict 'refs'; 

    my $caller = caller; 

    while (my ($name, $symbol) = each %{__PACKAGE__ . '::'}) { 
     next if  $name eq 'BEGIN'; # don't export BEGIN blocks 
     next if  $name eq 'import'; # don't export this sub 
     next unless *{$symbol}{CODE}; # export subs only 

     my $imported = $caller . '::' . $name; 
     *{ $imported } = \*{ $symbol }; 
    } 
} 
+0

Leon의 답변은 http://stackoverflow.com/questions/607282/whats-the-best-way-to-discover- all-subroutines-a-perl-module- –

2

아마도 당신은 단순히 서브 정의에 속성을 추가하여이 내보낼 잠수정을 표시 할 수 있습니다 CPAN에 수출 중 하나 * 모듈에 관심이있을 것인가? 은 (는 생각했다 어느 기억하지 마십시오.)

+0

이 당신이 생각한 것입니까? http://search.cpan.org/dist/Exporter-NoWork/lib/Exporter/NoWork.pm –

+0

@Chas. Owens - 아니, 나는 생각했다 Exporter :: Simple – ysth

1

는 일반적으로 발신자 이름 공간에 모듈에서 모든 sub의 덤프하는 것이 현명하지 않지만, 가끔 유용하다 (더 DRY!) 자동 @EXPORT_OK를 생성하는 변수는 %EXPORT_TAGS입니다.

가장 쉬운 방법은 내보내기를 확장하는 것입니다.

package Exporter::AutoOkay; 
# 
# Automatically add all subroutines from caller package into the 
# @EXPORT_OK array. In the package use like Exporter, f.ex.: 
# 
#  use parent 'Exporter::AutoOkay'; 
# 
use warnings; 
use strict; 
no strict 'refs'; 

require Exporter; 

sub import { 
    my $package = $_[0].'::'; 

    # Get the list of exportable items 
    my @export_ok = (@{$package.'EXPORT_OK'}); 

    # Automatically add all subroutines from package into the list 
    foreach (keys %{$package}) { 
     next unless defined &{$package.$_}; 
     push @export_ok, $_; 
    } 

    # Set variable ready for Exporter 
    @{$package.'EXPORT_OK'} = @export_ok; 

    # Let Exporter do the rest 
    goto &Exporter::import; 
} 

1; 

참고 호출 스택에서 우리를 제거 goto의 사용 : 간단한 예제는이 같은 것입니다.

더 완벽한 예제는 여기에서 찾을 수 있습니다. http://pastebin.com/Z1QWzcpZ 서브 루틴 접두사에서 태그 그룹을 자동으로 생성합니다.

1

경우 1

도서관은 다음과 같습니다

package mycommon; 

use strict; 
use warnings; 

sub onefunctionthatyoumadeonlibary() { 
} 
1; 

당신은 일반 전화, 사용할 수 있습니다 : : :

#!/usr/bin/perl 
use strict; 
use warnings; 
use mycommon; 

common::onefunctionthatyoumadeonlibary() 

경우 2

도서관은, yousimple는 내보낼 :

같은 "네임 스페이스"에

사용을 :

#!/usr/bin/perl 
use strict; 
use warnings; 
use mycommon qw(onefunctionthatyoumadeonlibary); 

onefunctionthatyoumadeonlibary() 

는 또한 우리가이 이가지 경우 혼합 할 수 있습니다, 우리는 패키지 이름과 다른 함수를 호출하지 않고 그것을 사용하는 일반적인 기능을 내보낼 수있는 우리 단지 패키지 이름으로 호출하면 내보내기 할 필요가 없습니다.

관련 문제