Skip to content

Instantly share code, notes, and snippets.

@am0c
Created February 16, 2011 09:53
Show Gist options
  • Select an option

  • Save am0c/829110 to your computer and use it in GitHub Desktop.

Select an option

Save am0c/829110 to your computer and use it in GitHub Desktop.
Exporter 모듈 궁금증
--------------
#!/usr/bin/env perl
use warnings;
use strict;
use CHILD;
exported_ok();
--------------
package CHILD;
use warnings;
use strict;
BEGIN {
use Exporter ();
our @ISA = qw(Exporter);
our @EXPORT = qw(exported_ok);
}
sub exported_ok {
print "exported ok\n";
}
1;
---------------
여기서 BEGIN 블락 내에서 정의한 패키지 변수는 CHILD 패키지에 존재하지만 접근할 수 없다.
예를들어 CHILD 패키지 내에 다음과 같은 문장을 적으면:
print "@EXPORT";
이런 오류가 나타난다:
Variable "@EXPORT" is not imported at CHILD.pm line 12.
Global symbol "@EXPORT" requires explicit package name at CHILD.pm line 12.
Compilation failed in require at t.pl line 4.
BEGIN failed--compilation aborted at t.pl line 4.
단 이렇게 재선언하면 제대로 출력된다:
our @EXPORT;
print "@EXPORT";
오류의 문장을 보면 unimported됨을 알 수 있다.
perl은 오류를 발생하는 시점에서 이 심볼이 정의되었긴 하다는 것을 아는 것처럼 보인다.
---------------
두번째 문제는 Exporter 모듈을 위의 코드와 같이 작성할 경우 잘 작동한다는 것이다.
BEGIN 블락 내에서 use하는 시점에서 암시적으로 import되면서,
아마도 Exporter가 현재 패키지에 몇몇 심볼을 대신 export해주기 위해
직접 심볼 테이블을 조작할 것이다.
그런데 조작하기 위해서는 @ISA 패키지 변수에 접근해야 한다.
따라서 @ISA 변수는 현재 모듈을 use하는 순간에 상속받은 import를 수행하면서 접근할 것이다.
근데 그 때는 이미 @ISA 변수가 unimported인가 뭔가하는 처음보는 증상으로 접근이 불가능하다.
근데 왜 되는가?
---------------
세번째 문제는
현실적으로 괴상한 시도이기는 하지만,
Exporter 모듈을 사용하는 패키지에서
sub import {
my $class = shift;
my @arg = @_;
....
....
$class->SUPER::import(@arg);
}
해서 Exporter가 export한 심볼을 다시 unexport하는 것이 과연되냐는 것인데,
몇몇 고려해야할 사항이 생길 것 같다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment