2009-09-23 2 views
10

나는 Perl에서 한 가지를하는 법을 모르며 나는 근본적으로 잘못된 것을하고 있다고 느낍니다.모듈 경로를 기준으로 파일을로드하는 방법은 무엇입니까?

나는 더 큰 프로젝트를하고있다. 그래서 나는 다른 모듈로 작업을 나누었다. 모듈을 project 디렉토리의 "modules /"서브 디렉토리에 넣고이 디렉토리를 PERL5LIB 및 PERLLIB에 추가했습니다.

이 모든 모듈은 모듈 파일의 관점에서 볼 때 기본 프로젝트 디렉토리의 외부 파일 ("../configure.yaml")에 저장된 일부 구성을 사용합니다.

하지만 지금은 "사용"을 통해 모듈을 사용할 때 모듈의 모든 상대 경로는 모듈 자체의 디렉토리가 아니라이 모듈을 사용하는 스크립트의 현재 디렉토리에서 가져옵니다. FindBin 또는 다른 것을 사용할 때도 아닙니다.

모듈 경로의 상대 경로로 파일을로드하려면 어떻게해야합니까? 그것은 심지어 가능하거나 권장 할만한가?

답변

13

모듈이 % INC 해시에서로드되는 Perl 저장소. 당신은 상대적 일을로드 할 수

package Module::Foo; 
use File::Spec; 
use strict; 
use warnings; 

my ($volume, $directory) = File::Spec->splitpath($INC{'Module/Foo.pm'}); 
my $config_file = File::Spec->catpath($volume, $directory, '../configure.yaml'); 

% INC의 키도 등 윈도우, VMS,

참고 그에 추가가 .pm과 /의 ::에 대한 엄격한 번역을 기반으로 @INC에 상대 디렉토리를두면 % INC의 값은 현재 디렉토리와 관련 될 수 있으므로 require/use와 % INC 사이에서 디렉토리를 변경하면주의해야합니다.

+0

고마워. –

-3

use Module 전화 번호를 require Module (또는 require Module; Module->import(LIST))으로 변경하십시오. 그런 다음 디버거를 사용하여 모듈로드 프로세스를 수행하고 Perl이 파일을로드하는 위치를 확인합니다.

+2

, 나는 내 프로그램에 버그가 있다고 생각하지 말아 단순하게하다 쓰기, 예를 들어, LoadFile ("../ configure.yaml"); 모듈에 넣고 그 모듈을 다른 곳의 스크립트에서 사용합니다. Perl은 모듈 파일이 아닌 스크립트 파일의 상대 경로로 사용합니다. 필요하거나 디버깅이 실제로 도움이되지 않는다. 문제가있는 곳을 알고있다. 나는 그걸로 무엇을 해야할지 모르고있다. –

8

세계 %INC 테이블에는 use '또는 require'd 개의 모듈이 모두 포함되어 있으며 Perl이 해당 모듈을 찾은 곳과 연관되어 있습니다.

use YAML; 
print $INC{"YAML.pm"}; 

>> /usr/lib/perl5/site_perl/5.8/YAML.pm 

더 도움이 되셨습니까?

+0

네, 감사합니다 :) –

9

이 문제를 해결하기 위해 존재하는 모듈은 File::ShareDir입니다. FindBin을 시도하고있는 올바른 길을 가고 있었지만 FindBin은 항상 프로그램 인을 찾았지 만 FindBin은 사용중인 모듈이 아닙니다. ShareDir은 ysth의 솔루션과 아주 비슷하지만 좋은 인터페이스에 싸여 있습니다. 난 그냥 몰라, 어떻게 작성 : 그냥 경우 -

사용은

my $filename = File::ShareDir::module_file(__PACKAGE__, 
    'my/data.txt'); 
# and then open $filename or whatever else. 

또는

my $dirname = File::ShareDir::module_dir(__PACKAGE__); 
# Play ball! 
관련 문제