펄모듈 동적으로 로드하기

김현승

SYNOPSIS


eval("use CGI");
if ($@) { die "Load error"; }

DESCRIPTION

스크립트의 효율문제로 모듈을 선택하여 로드하고 싶을때 이를 해결해보자.

require 를 이용한 방법

require는 라이브러리가 될 파일의 내용을 그 위치에다가 직접써넣는 C에서의 include 문과 같다고 보면되겠습니다.
코드를 로드하기보다는 삽입한다고 생각하시는게 더 가깝습니다.

## 삽입을 피해갈수 있다
if ( 0 ){
  require "cgi_lib.pl";
}

## 포함할 스크립트의 이름을 동적으로 지정
$file = "cgi_lib.pl"
require $file;

use 를 이용한 방법

use는 require와 다른 특성을 갖는데,
첫째, 중복로딩을 막습니다.
둘째, 로직흐름과 상관없이 새로운 영역에 로딩됩니다.
컴파일시에 문맥을 따지지않고 발견되는 use문을 단한번만 처리하게 된다.
그래서 require 와 같이 쓰려고 한다면

## 피할수 없다!!
if ( 0 ){
  use CGI;
}

## 스칼라를 인수로 주는게 아니다!!
$file = "CGI"
use $file;

## 루프밖에서 한번만 로드한다!!
for(1..10){
	use DoSomething;
}
이렇게 엄청난 혼돈이 오게됩니다. use는 표현식이 아니기 때문입니다.
하지만 use를 쓰면 좀더 의존성이 적은 라이브러리를 작성하게 되는 이득을 볼수가 있습니다.
그러나 use만으로는 모듈을 선택하여 로드할수 없습니다. 어디에 적어주든간에 로드되어버리기 때문입니다.

use로 require처럼 원하지 않는 모듈은 피해가는 방법...


if ( 0 ) {
  eval( "use CGI");
}
와 같이 만들어주면 동적으로 use할수 있습니다. 물론 비슷하게 모듈명을 동적으로 지정해줄수도 있습니다.

$m = "CGI";
eval( "use $m");

동적로드 실패의 처리

require 는 디렉토리의 파일을 직접 지정하기때문에 파일의 존재만 확인하면 동적으로 로드하기 전에 실패를 막을수 있습니다.
하지만 use는 모듈이 설치된 패스들을 찾아 로드하기때문에 일일이 찾아주기도 힘들뿐더러 종속성까지 미리 체크해줄수 없습니다.
그래서 동적로드후에 처리합니다.
eval 문은 스크립트의 치명적인 에러를 감춰(catch)줍니다. 그리고 $@ 변수에 그 에러를 저장하게 됩니다.
이것을 이용해서

eval("use CGI");
if ($@) { die "Load error"; }
와 같이 하면 CGI모듈이 없을때 Load error 을 출력하고 스크립트를 종료합니다.

AUTHOR

김현승(Kim, hyuns) - sng2nara@hotmail.com

REFERENCE

펄코어문서

COPYRIGHT

Copyright 2002, Hyuns Kim. All right reserved.

This is a PMDocs of Perlmania. You may copy or redistribute it under the same terms as Perl itself. 

Comments