2010-06-04 7 views
6

패키지/모듈 문제, 기본적인 사용법은 다음과 같습니다펄 - 나는 펄 모듈을 사용하여 읽은 모든 것을에서

  • <name>이의 파일 이름입니다 문 package <name>을 포함 .pm 확장명 모듈 파일 확장 모듈이없는 모듈.
  • 모듈을 사용하는 코드 파일에는 use <name>; 문이 포함되어 있습니다.

코딩중인 응용 프로그램에는 약 5 개의 모듈을 사용하는 하나의 주 코드 스크립트가 있습니다. 모듈에 package <name> 문을 포함하는 것을 잊었지만 내 코드는 여전히 use <name> 문으로 올바르게 실행되었습니다. 모듈 중 하나에서 Undefined subroutine 오류를 받기 시작 했으므로 패키지 문을 각 모듈에 추가했습니다. 이제 나머지 모듈은 이 중지되었습니다. 뭐라 구요?

예 :

mainapp.pl

#!/usr/bin/perl 
use UtyDate; 
my $rowDate = CurrentDate("YYYYMMDD"); 

UtyDate.pm 나는 위의 코드를 실행하면, 나는 오류 Undefined subroutine &main::CurrentDate called at...를 얻을 수

#!/usr/bin/perl 
package UtyDate; 
sub CurrentDate 
{ 
    #logic 
} 
return 1; 

. 그러나 UtyDate.pm에서 package UtyDate; 행을 제거하면 오류가 발생하지 않습니다. 이 상황은 여러 모듈에 존재하지만 모든 모듈에는 존재하지 않습니다.

분명히 더 많은 코드가 표시되지 않지만 내가 보여주지 않은 코드가 여기에 표시된 패키지/사용 구조에 어떻게 영향을 미칠 수 있는지 혼란스러워합니다.

답변

10

작동하지 않습니다. 그런 다음 import가 모듈의 패키지 이름에서 호출됩니다. 그래서, use Foo;는 모든 코드는 주 응용 프로그램 코드에서 사용되는 패키지 main,에서 실행 되었기 때문에 BEGIN { require Foo; Foo->import; }

귀하의 코드가 package 선언하지 않고 작업과 동일합니다.

package 선언을 추가 할 때 정의한 서브 루틴이 더 이상 main이 아닌 UtyDate에 정의되어 있기 때문에 작업이 중지되었습니다.

정규화 된 이름 UtyDate::CurrentDate();을 사용하거나 모듈 use을 사용할 때 현재 이름 공간으로 서브 루틴을 가져 와서 서브 루틴에 액세스 할 수 있습니다.

UtyDate.pm

package UtyDate; 
use strict; 
use warnings; 

use Exporter 'import'; 

# Export these symbols by default. Should be empty!  
our @EXPORT =(); 

# List of symbols to export. Put whatever you want available here. 
our @EXPORT_OK = qw(CurrentDate AnotherSub ThisOneToo); 

sub CurrentDate { 
    return 'blah'; 
} 

sub AnotherSub { return 'foo'; } 

주요 프로그램 :

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

use UtyDate 'CurrentDate'; 

# CurrentDate is imported and usable.  
print CurrentDate(), " CurrentDate worked\n"; 

# AnotherSub is not 
eval { AnotherSub() } or print "AnotherSub didn't work: [email protected]\n"; 

# But you can still access it by its fully qualified name 
print UtyDate::AnotherSub(), " UtyDate::AnotherSub works though\n"; 

대한 추가 정보를 원하시면 Exporter 문서를 참조하십시오.

+2

OP는' perlmod' (http://search.cpan.org/perldoc/perlmod)는'Exporter'에서 계속되고있는 것을 이해하기위한 전제 조건으로 먼저 나온 것입니다. – mob

+0

큰 설명, 감사합니다. 제가 본 몇몇 예에서 Exporter가 사용 된 것을 보았습니다. 하지만 전부가 아니기 때문에 무관계하다고 생각했습니다. 나는이 문서를 너무 잘 살펴볼 것입니다. – brydgesk

3

당신은 수출상 펄 코드가 없습니다.

package UtyDate; 
BEGIN { 
    use Exporter(); 
    use vars qw($VERSION @ISA @EXPORT); 
    $VERSION = "1.0.0"; 
    @ISA = qw(Exporter); 
    @EXPORT = qw(&CurrentDate); 
} 

이 링크를 참조하십시오 : 당신은 패키지 문 아래에 오후 파일의 상단에 다음과 같이 뭔가를 추가해야합니다 또는 회색의 제안에 http://perldoc.perl.org/Exporter.html#DESCRIPTION

+0

http://p3rl.org/Exporter#Good_Practices에 따라 편집하거나 처음에는 [Sub :: Exporter] (http://p3rl.org/Sub::Exporter)를 사용하십시오. – daxim

1

을, 당신은이 작업을 수행 할 수 있습니다

use UtyDate; 
UtyDate::CurrentDate(...); 
0

그레이는 지적으로 수출을 사용하는 외에, 당신은 (추한하지만 작품) 또한 모듈 이름으로 함수를 호출 할 수 있습니다 ..

당신 쿵푸 그들은 (모듈 이름으로 정의 됨) differen 네임 스페이스에 지금부터 nctiond/절차는 모듈을 사용하는 경우, 모듈의 코드는 컴파일 시간에 실행됩니다

use UtyDate; 

UtyDate::CurrentDate() 
+1

그것은 추한 것이 아닙니다; 이것이 OO 스타일로 작성되지 않은 함수를 호출하는 표준 방법입니다. – Ether

+0

네임 스페이스는 모듈의 이름이 아닌'package' 호출에 의해 정의됩니다. 패키지 이름과 모듈 이름이 같은 규칙 일뿐입니다. – mob

+0

@Ether : 표준이 '추악하지 않다'와 같지 않습니다. 나는 두려워합니다. 게다가, 나는 Grey의 'solution'에 비해서 '추한'을 의미했다. 이미 쓰여진 코드에 훨씬 적은 변경을 요구했다. ('많이 바뀐다'는 내가 '못생긴'이라고 생각한다.) YMMV – lexu