메인 컨텐츠로 가기

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관 보기.

모든 정보가 안전하게 전송되었습니다.

  • 닫기 [x]

Cultured Perl: Perl로 애플리케이션 구성

CPAN AppCongfig 모듈과 데이터베이스 지향 구성

Teodor Zlatanov, 프로그래머, Gold Software Systems
Teodor Zlatanov는 1999년 보스톤 대학에서 컴퓨터 공학 석사학위 취득했다. Perl, Java, C++ 를 사용하여, 1992년부터 프로그래머로 일하고 있다. 주요 관심 부분은 text parsing, 3-tier 클라이언트/서버 데이터베이스 아키텍처, UNIX 시스템 관리, CORBA 및 프로젝트 관리에 대한 오픈 소스 작업이다.

요약:  파일 기반 구성은 수동식(hand-built) 메소드를 사용할 경우 파손되기 쉽다. Teodor Zlatanov는 AppConfig 모듈이 Perl 프로그램용 로컬 구성 기억장치(storage)를 어떻게 처리하고 네트워크를 통한 머신과 액세스 가능한 데이터베이스에 구성을 추척하는 방법에 대해 설명한다.

원문 게재일:  2000 년 10 월 01 일
난이도:  초급
페이지뷰:  1281 회
의견:  


모든 프로그램(디렉토리 목록 출력 프로그램부터 웹 브라우저에 이르기 까지)이 갖추어야 할 첫째 조건 중 하나는 사용자의 구성(설정)이 가능하도록 하는 것이다. 파일 기반의 구성과 명령 행 옵션의 조합은 사용자 구성에 있어서 오랫 동안 유연성있게 사용되어 온 솔루션이다. Perl 프로그램은 대개 이러한 접근법을 채택하고 때로 구성 파일과 명령 행 파싱 루틴(command-line parsing routines)을 사용한다.

이 글에서 사용할 명령 행 파싱(command-line parsing)은 약간 복잡하다. 만약 간단한 인자보다 고수준의 파싱을 사용할 것이라면 나중의 혼돈을 피하기 위해 Parse::RecDescent(또는 같은 역할의 파싱 모듈) 사용을 권장한다. 복잡한 명령 행 파싱에 대한 논의는 Perl 프로그램 관련 자료인 이전 글(US)을 참고한다.

Perl 5.005 또는 그 이상의 버전과 CPAN AppConfig 모듈이 설치되어 있는지 확인하라. 또한 Persistent:MySQL 이나 사용하고 있는 데이터베이스에 맞는 Persistent 클래스가 필요하다. CPAN을 참고한다. (참고자료)

DIY식 간단한 접근법

올바른 툴을 사용할 경우, 이론적으로 모든 사용자가 구성 파서를 구축할 수 있다. 예를 들면 Perl Cookbook은 빠르게 시작할 수 있는 구현 방법을 보여준다. 이런 종류의 구현을 할 경우, 구성 파일 파서 작성이 매우 어려울 수 있다.

이런 방식의 프로젝트는 다음과 같은 실질적인 복잡한 문제를 발생시킬 수 있다.:

  • 구성 파일에서 공백 행과 주석
  • 에러 행(철자가 틀린 키워드 등) 및 중요도의 의문 사항
  • 다양한 데이터 구조(부울, 스칼라, 배열, 해시)가 필요할 때 자체 파서 작성
  • 다중 구성 파일
  • 변수 디폴트
  • 명령 행 옵션과 파일 구성의 통합 및 상호작용 제어
  • 다른 DIY 구성 파일 형식에서 사용자 교육 (예: 행에 '=' 이 없으면, 자체 작동할 것이다. 주석은 '#'으로 시작한다. 그런데 주석 자체에서 그렇게 시작해야 한다. 키워드는 대문자, 값은 소문자를 사용한다는 점을 주의한다. 필수 키워드들도 있다.)
  • 모듈 재사용 대신 버그 위험이 있는 구성 코드 복사 또는 다시 쓰기
  • 흔히 사용하는 키워드의 해시 대신 일관성 있는 인터페이스를 포함한 객체 구성 만들기

AppConfig 이 모든 것을 처리한다. DIY는 사용하지 않는 것이 좋을 것 같다.


AppConfig로 해결하기

Andy Wardley의 AppConfig CPAN 모듈이 위에 기술된 모든 문제 해결에 도움을 주지만, 만병통치약은 아니다. 때때로 AppConfig사용을 위해 재작성이 필요하다.

DIY 또는 AppConfig의 사용이 불확실하면 사용자 경험을 토대로 하여 작성하는 것에 따라 결정해야 한다. 그러나 AppConfig 보다 DIY 접근 방법이 더 나은 경우는 별로 많지 않다고 생각한다.

AppConfig로 무엇을 할 수 있는지 차근차근 설명하겠다. (이전 섹션에서 언급되었던 문제들이다):

  • 구성 파일에서 공백 행과 주석 AppConfig는 공백 행과 주석을 알 수 있으며, 그것들을 무시한다.
  • 오자의 에러 행 중에서 중요한 것과 무시해도 좋은 것 잘못된 세팅을 무시하거나 또는 프로그램을 취소하도록 AppConfig의 민감도를 설정할 수 있다. 철자를 대체하는 것이 가능한 경우에는 키워드에 별칭을 줄 수 있다.
  • 다양한 데이터 구조(부울, 스칼라, 배열, 해시)가 필요할 때 자체 파서 작성: AppConfig는 이 모든 데이터 구조를 처리하지만, 중첩 처리는 하지 않는다. 해시 또는 배열을 중첩 시킬 필요가 있으면. DIY로 하거나 AppConfig를 보조해야 한다.
  • 다중 구성 파일 AppConfig는 각 구성 파일의 설정을 차례로 로딩하면서 필요한 만큼의 다수의 구성 파일을 처리한다. 또한 스택의 하단에 삽입된 값이 상단까지 도달하지 않도록 배열 및 해시를 재설정하여 AppConfig를 보조할 수 있다.
  • 변수 디폴트: AppConfig은 변수 디폴트를 제공한다. "-variable" 신텍스는 구성 파일에서 변수를 디폴트 상태로 리셋한다.
  • 명령 행 옵션과 파일 구성의 통합 AppConfig는 Getopt::Std 및 Getopt::Long 명령 행 옵션 파싱을 모두 지원한다. 파싱은 구성 파일 읽기 전후에 수행될 수 있다.
  • 다른 DIY 구성 파일 형식으로 사용자 교육: AppConfig는 유연성있는 표준 포맷을 사용한다. "KEYWORD value" 이나 "KEYWORD=value"은 모두 스칼라에 적용된다. 배열을 추가할 수 있어서, "ARR=1" 다음에 "ARR=2"를 하면 1과 2의 요소를 가진 ARR 배열을 생성한다. 또한 부울 옵션을 "bool", "nobool", "!bool", "bool on", "bool off", "bool yes"("bool no"는 유효하지 않음), "bool 1", "bool=0"(악명 높은 상징성 논리 창시 자인 Dr. George Boole은 안심할 수 있었을 것이다-참고자료 참조)으로 지정할 수 있다. 해시 옵션은 "KEYWORD PARAMETER=value"로 지정된다. 여기서 value 는 키 PARAMETER를 가진 해시 항목이다.
  • 모듈을 재사용하는 대신 버그 위험 있는 구성 파일 복제 또는 다시 쓰기: 이 부분에 있어서 AppConfig는 상당히 안정적이다. 또한 모듈과의 인터페이스도 변경되지 않는다. 수천명의 프로그래머들에 의해 테스트되어 온 것으로 사용하지 않을 이유가 없다.
  • DIY 우연적 해시 대신 일관성 있는 인터페이스를 포함한 객체 만들기: 일관성 있는 API는 메인 프로그램에서 구성 핸들러를 추출하여 핸들러의 인터페이스를 단순화한다. 이 접근법은 또한 데이터 구조와 직접 작동하는 대신 고유 메소드가 있기 때문에 버그가 적다.

AppConfig 선택 이유를 검토하였으니, 이제 AppConfig 사용법에 대한 완벽한 예제를 보자. 고급 기능은 다음 섹션에서 살펴 볼 것이다. 변수는 스칼라, 부울 및 배열 용 "-varname value" 및 해시 용 "-varneme key=value"으로 명령 행에 설정할 수 있다. config.pl이 구성 파일이고 예제는 다음과 같다. :


# blank lines are ignored
# set a boolean debug
# set a scalar name=E.T.
# set an array hosts = dbhost hosts = backuphost
# reset the hosts array -hosts
# add new values to hosts hosts = firewall hosts = farewell
# set a hash phone joe = 222-333-4444 phone marge = 555-666-7777


AppConfig 고급 사용법

AppConfig은 EXPAND 설정에 따라 여러 레벨에서 변수 확장을 할 수 있다. 상세한 사항은 AppConfig 문서를 참고한다..


# expand all variables, globally
my $config = AppConfig->new({ GLOBAL => { EXPAND => EXPAND_ALL } }); 
# expand just HOME_DIR as UID, so "~username" will work as in the shell $config->define('HOME_DIR => { ARGCOUNT => ARGCOUNT_ONE, EXPAND
=> EXPAND_UID });

INI-스타일 섹션은 또 하나의 유용한 AppConfig 특징이다. 행 자체가 구성 파일에서 [section]을 이용하여 모든 키워드의 서두를 섹션 이름과 언더라인'_'으로 시작하여 파일 또는 다음 섹션의 끝까지 사용할 수 있다. 예제는 다음과 같다:


[file]
location = /tmp
type = txt
name = accounts.txt
[database]
host = wyrm
user = slayer
password = amethyst

다음은 동일한 내용이다:


file_location = /tmp
file_type = txt
file_name = accounts.txt
database_host = wyrm
database_user = slayer
database_password = amethyst

AppConfig 구성 객체는 varlist( ) 함수로 검사할 수 있다. AppConfig 객체에서 각 변수 내용을 인쇄하는 코드는 아래와 같다. varlist ( ) 함수는 정규식을 취해야만 하는 약간의 트릭을 사용한다.(빈 문자열은 유효하지 않다.)


use Data::Dumper; # for hash and array references
my %varlist = $config->varlist('.*'); foreach my $varname (keys %varlist) { print "Variable name $varname, value = ", Dumper $config->get($varname), "\n"; }

AppConfig의 Getopt::Long 인터페이스는 Getopt::Long 모듈로의 완벽한 액세스를 허용한다. 아래는 명령 행에서 매개변수를 파싱하도록 호출되는 Getopt::Long에 대한 가변 매개변수를 정의한 코드이다.


$config->define("help|h|!"); # define a boolean
$config->define("code|c|=i"); # define a scalar integer
$config->define("list|l|=f@"); # define a array of floating point values only
$config->define("uids|u|=f%"); # define a hash of floating point values only
$config->getopt(); # instead of args(), to use the Getopt::Long options

AppConfig에서 변수 확인도 가능하다. 이 말은 변수가 정규식(한 개의 코드까지)을 조회하여 간단하게 무의미한 것이나 악의성 있는 것에 대한 값 설정을 거부할 수 있다는 뜻이다.


# the username validation succeeds only when it is exactly "joe"
# the password validation succeeds when it contains "joe" or "joE"
$config->define(
                'USERNAME' => { ARGCOUNT => ARGCOUNT_ONE,
                                VALIDATE => sub # subroutine validation
	       				    {
					     my $varname = shift @_;
					     my $value = shift @_;
					     print "$varname = $value\n";
					     return ($value eq "joe");
					    }
	                      },
                'PASSWORD' => { ARGCOUNT => ARGCOUNT_ONE,
				VALIDATE => "jo[Ee]" # regex validation
		              }
               );

AppConfig은 자동 트리거를 할 수 있어 변수값이 변경될 때 마다 조치가 수행 될 수 있게 한다. AppConfig은 서브 루틴으로 전송되어 기타 변수 변경이 단일 변경에 의해 트리거 될 수 있도록 한다.


$config->define(
                'USERNAME' => { ARGCOUNT => ARGCOUNT_ONE,
                                ACTION => sub # autoaction
       				          {
					   my $config = shift @_;
					   my $varname = shift @_;
					   my $value = shift @_;
					   print "$varname = $value\n";
					  }
	                      }
               );


AppConfig 제한

AppConfig는 변수에 삽입된 코드를 처리하지 않는다. 구성 파일에 있어 코드가 불필요하다. 더구나 사용자 임의 코드 실행을 허용하는 것이 효과적이지 않을 수 있다. 변수와 연관된 자동 작동(auto-action) 및 유효성 검사 서브루틴이 변수 평가를 위해 조정될 수 있지만, AppConfig는 자동 변수 평가를 제공하지는 않는다. 필요할 경우 변수를 선택하여 다음 설명과 같이 eval( )을 실행한다. 사용자에게 프로그램에 대한 제어 수준을 확인하는 것이 우선이라는 것을 명심하라.


foreach my $varname ('username', 'password')
{
 $config->set($varname, eval $config->get($varname));
}

AppConfig에서 INI-스타일 섹션은 코드를 정의한다. 그러나 섹션은 미리 그 유용성이 점검되어야 한다. 섹션이 상위 객체에 중첩된 신규 AppConfig 객체를 생성할 수 있도록 설계하는 것이 좋다. 어쨌든 이런 문제는 큰 문제가 아니다.

간단한 테스트를 해보면 로딩과 실행 속도는 AppConfig 사용에 아무 문제가 없다. 매우 작은 모듈이면서 사이즈/스피드 패널티도 무시될 수 있다. 사용자 프로그램이 정확한 시간 값을 필요로 하는 것이라면 AppConfig를 사용할 때와 사용하지 않을 때의 시간을 측정하여 사용할 가치가 있는지 결정해야 한다.

주로 API 덕분에 AppConfig 복잡성과 학습곡선 레벨은 기대치 이하이다. 초보 프로그래머에게 특히 혼란스럽다. 그러나 대체로 기존 Perl을 경험했던 프로그래머에게는 중요한 문제는 아니다.

AppConfig의 파싱 제한은 유용성의 문제 때문이다. 명령 행 옵션의 고급 파싱이 필요하면 Perl 프로그램에 대한 이전 글(AppConfig이 구분 파싱 불가능한 검색 능력에 관한 내용)를 참조 바란다.


AppConfig 및 Persistent::DBI으로 데이터베이스에 구성을 업로딩하기

이 섹션을 읽기 전에 Persistent 모듈 사용의 데이터 저장에 관한 자료를 참조하기 바란다. 또한 Perl 레퍼런스 및 SQL 데이터베이스에 대한 이해가 있어야한다. 예제에서는 MySQL 데이터베이스 및 그에 상응하는 Persistent 모듈을 사용한다. 다른 데이터베이스(예를 들어, Postgres 또는 Oracle)를 사용한다면, 그에 맞는 다른 Persistent 모듈을 찾아야 한다.

데이터베이스에 구성을 적용하기 전에, 데이터베이스 스키마가 미리 설계되어 있어야 한다. 다시 말하면 데이터 저장 및 복원을 위한 코드를 작성하기 전에 어떤 데이터를 저장하고자 하는지 미리 결정해야 한다. 예제에서는 부울, 스칼라, 배열 및 해시를 각각의 별도 테이블에 저장한다.

이 접근법이 반드시 필요한 것은 아니다. 모든 데이터 유형에 대한 하나의 테이블만을 가지거나, 목적 별로 구분된 테이블들을 가질 수 있다. 내가 제시하는 예는Persistent 구성 구현에 필요한 한 가지의 방법이지 유일한 것은 아니다.

이 글에서 제시하는 스키마로 대부분 목적에 사용되기에 충분하다. 값과 키 길이에 있어 제한이 있으나 코드에서 쉽게 조정될 수 있다. 그러나 배열과 해시 요소 ID의 생성에 있어서 문제가 발생될 수 있다. 이런 경우, 완벽한 솔루션은 없다. 문제 해결하기 위한 다양한 접근법이 있을 뿐이다. 관련 데이터베이스에 임의의 구조화된 데이터 저장 문제가 항상 까다롭다.

AppConfig::State의 _argument() 메소드를 사용할 것이다. 메소드에 관한 상세한 정보는 AppConfig::State 사용설명서를 참조한다. 메소드 이름을 알고 있으면 그 메소드는 우리가 어떤 변수를 처리하고 있는 지를 즉시 알려 준다. MySQL 데이터베이스 및 상응 Persistent 모듈에 의한 사용자 .

코드의 예제에 대한 상세한 것은 Persistent config.pl을 참조한다.


결론

AppConfig와 Persistent 클래스는 단순한 공동 작업으로 좋은 성과를 낼 수 있다. 이전 섹션에서 나타난 persistent-config 스크립트는 단축키 및 변수명으로 대부분의 구성을 처리할 수 있다. 그러나 개선되어야 할 부분이 있다. 일단 스크립트가 작성되면 네트워크 어느 곳에서나 스크립트를 시작할 수 있으며 중앙 호스트에서 현재 구성을 로드 할 수 있다. 이 개선 작업으로 데이터베이스 구성에 대해 알게 될 것이고 신규 네트워크 중심 방식으로 애플리케이션을 볼 수 있도록 도와 줄 것이다.

코드 재사용은 일반적인 모듈의 가장 큰 특징 중 하나이다. 특별히 AppConfig의 특징이라 할 수 있다. DIY(Do It Yourself) 접근법이 버그와 지연을 일으키는 경우, AppConfig는 대부분 구성의 요구사항을 만족시킬 충분히 효과적인 단일 솔루션을 제공한다.

"AppConfig limitations" 섹션에 기술된 제한을 매우 미약하다. 물론 AppConfig에 맡기기 이전에 프로젝트에 가장 적합한 것이 어떤 것인지를 결정해야 한다. 여기에 제시된 정보가 특정 프로젝트에 어떻게 적용되는지 파악하고 AppConfig 사용설명서를 참고하기 바란다.

AppConfig에 전체 작업을 맡기지 말고 필요한 부분만 선택한다. 프로그램 절반을 구성 파일에 올리는 것이 흥미로울 지 모르나 그렇게 되면 사용자의 항의가 빗발칠지도 모른다. 간략하고 논리적인 구성 파일을 만들라. AppConfig이 제공하는 명령 행 옵션(command-line options)을 포함하여 프로그램 구성 신텍스에 대한 상세한 내용을 작성한다.


참고자료

필자소개

Teodor Zlatanov는 1999년 보스톤 대학에서 컴퓨터 공학 석사학위 취득했다. Perl, Java, C++ 를 사용하여, 1992년부터 프로그래머로 일하고 있다. 주요 관심 부분은 text parsing, 3-tier 클라이언트/서버 데이터베이스 아키텍처, UNIX 시스템 관리, CORBA 및 프로젝트 관리에 대한 오픈 소스 작업이다.

잘못된 도움말 신고

부정사용 신고

감사합니다. 이 항목은 운영자가 관심을 표시했습니다.


잘못된 도움말 신고

부정사용 신고

제출실패 신고. 나중에 다시 실행해주세요.


디벨로퍼웍스 로그인


IBM ID가 필요하세요?
IBM ID를 잊으셨습니까?


비밀번호를 잊으셨습니까?
비밀번호 변경

developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


developerWorks에 처음 로그인하면 developerWorks프로파일이 생성됩니다.귀하의 프로파일에서 동의하신 내용이 공개되지만 이 사항은 언제든지 변경 가능합니다. 귀하의 성명(숨김으로 체크되어 있어도 표시됩니다)과 디스플레이 이름은 게시한 컨텐츠나 사이트 엑세스시 표시됩니다.

화면상에 보여지는 닉네임을 정하세요.

처음 developerWorks에 로그인할 때 프로파일이 작성되므로, 이를 위해 디스플레이 이름을 선택해야 합니다. 선택하신 디스플레이 이름은 developerWorks에 게시한 컨텐츠에 표시됩니다.

3글자 이상 31글자 이하의 길이로 사용 가능합니다. dW커뮤니티 내에서는 보안상 이메일주소를 제외한 다른 이름을 지정하셔야 합니다.

3개의 &이나 대쉬를 포함해주시고 31글자내로 제한해주세요.


developerWorks 이용 약관에 동의하시는 경우 제출을 클릭하십시오. 이용 약관.

 


아티클 순위

의견

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=20
Zone=리눅스
ArticleID=18073
ArticleTitle=Cultured Perl: Perl로 애플리케이션 구성
publish-date=10012000
author1-email=
author1-email-cc=

태그

Help
검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오.

태그를 더 많이 보거나 적게 보기 위해 슬라이더 막대를 사용하십시오.

인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다.

내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.

검색 필드를 사용하여 My developerWorks 내에서 해당 태그가 사용된 모든 종류의 컨텐츠를 검색하십시오. 인기 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 최고 인기 태그를 보여줍니다. 내 태그는 특정 컨텐츠 존(예를 들어, 자바, 리눅스, WebSphere)의 귀하의 태그를 보여줍니다.