'perlmodstyle'에 해당되는 글 1건

  1. 2008/03/17 perlmodstyle

perlmodstyle

perlmodstyle 문서을 나름대로(?) 번역했습니다.
Perl을 배우는 입장에서 잘 이해되지 않는부분도 있었고 아예 해석이 불가능한 부분은 원문 그대로 두었습니다.

INTRODUCTION

이 문서는 펄 모듈작성을 위한 펄 커뮤니티의 "best practice"에 대해 설명할 것이다. 이는 perlstyle에서 권장되는 여러 사항들을 확장한 문서이다. perlstyle 문서를 미리 읽어두면 좋다. 이 문서는 모든 모듈개발자 특히, CPAN에서 모듈이 발표되기를 원하는 사람들에게 유용할 것이다. 중요한것은 모듈개발자에게만 보여질게 아니라 그 모듈의 사용자 관점에서의 스타일이라는 것이다. 이 문서에서 제공하는 가이드라인의 많은 부분은 모듈내부로의 적용 및 추정을 할수 있게 한다.

이 문서는 CPAN 모듈의 튜토리얼이라기 보단 스타일가이드인 perlnewmod 와는 다르다. It provides a checklist against which modules can be compared to determine whether they conform to best practice, without necessarily describing in detail how to achieve this. (it이 무엇을 말하는지 모르겠군요 ㅠ)

이 문서의 모든 권고사항들은 경험많은 CPAN 개발자와 사용자의 수많은 이야기들을 포함하고 있다. 각각의 권고사항은 이전에 했던 실수의 결과로 부터 얻어졌다. 이런 정보는 당신이 똑같은 실수나 불가피하게 그런 실수가 일어날수 있는 경우들을 피할 수 있게한다.

이 문서의 첫번째 섹션은 체크해야할 항목리스트를 제공한다. 그 다음 섹션은 각각의 항목에 대한 상세한 주제를 다루며 마지막 섹션 "Common Pitfalls"에서는 CPAN 저자들의 가장 잘 알려진 실수들을 설명한다.

QUICK CHECKLIST

체크리스트에 있는 각각의 아이템에 대한 자세한 설명이 아래에 있다.

시작하기전에

- 헛수고하지 마라(있는 모듈을 만들지 마라)

- 가능하면 존재하는 모듈을 패치하거나 하위클래스로 확장해라.

- 하나의 모듈은 자기자신의 역할에 충실히

- 어울리는 이름을 골라라

API

- API는 대부분의 프로그래머에게 이해하기 쉽게 만들어져야 한다

- 단순한 작업에 단순한 메소드

- 결과물로부터 기능적으로 분리해라

- 서브루틴 또는 메소드는 일관된 네이밍룰에 따라라

- 2개이상의 파라미터일때 해시 또는 해시레퍼런스를 사용해라

안정성

- 당신의 모듈을 use strict 와 -w 플래그를 이용해 안전하게 작성해라

- 안정적인 모듈은 이전버전과의 호환성을 유지하게 한다.

문서작업

- POD에 문서작업을 해라

- 목적, 범위 그리고 해당되는 프로그램을 기술해라.

- public하게 access 할 수있는 메소드나 서브루틴을 기술하고 파라미터와 리턴값을 포함해라.

- 문서에 사용예제를 제공해라.

- README 파일과 가능하다면 릴리즈노트,체인지로그 등등을 제공해라.

- 더많은 정보(URL,email)에 대한 링크를 제공해라.

릴리즈시 고려해야 할 것

- Makefile.PL 이나 Build.PL의 필요조건을 명시해라.

- use 와 함께 사용되는 펄 버전을 명시해라.

- 당신의 모듈로 한 테스트를 포함시켜라.

- 적당하고 일관된 버전번호를 선택해라(X.YY는 대부분 펄모듈의 넘버링 방식이다)

- 작은 수정에도 버전을 증가시켜라. 번호가 작은것은 문제가 되지 않는다.

- 패키지모듈을 만들때 "make dist" 를 사용해라.

- 적당한 라이센스를 골라라(GPL/Artistic이 좋다)

모듈 작성하기 전

모듈을 만들때 생각없이 무모하게 진행하지 마라. 약간의 신중함이 나중에 많은 수고를 덜어줄 수 있다.

모듈이 이미 존재하는가?

당신이 모듈을 만들 필요가 없을수도 있다. 펄에서 이미 만들어진게 있는지 체크부터해라. 만약 당신이 기가막힌 아이디어가 아니라면 다시 개발하는 헛수고는 하지마라. 이미 존재하는 모듈을 찾는 좋은 곳은 http://search.cpan.org/ 이다. modules@perl.org에 문의하라. 당신이 원하는 어떠한 모듈이 거의 대부분 존재한다면 재작성보다는 패치, subclass 그렇지 않으면 모듈확장을 고려해라.

각각의 모듈은 자신의 역할에 충실하자

명백히 위험성이 있음에도 불구하고 모듈들은 좀더 모듈화 되어왔다. 펄 개발자들은 그들의 프로그램의 일관적인 방향으로 만들기위해 모듈을 사용할 수 있다. 하지만, 중요한것은 그러한 부분(코드)이 올바른 형태여야 한다는 것이다. 개발자들은 작은 부분이 필요할때 큰 부분을 사용해서는 안된다.

당신의 모듈은 하나의 문장도 채 되지않는 명백히 정의된 유효범위를 가져야 한다. 당신의 모듈이 연관된 모듈의 구성원이 될 수있는가?

나쁜 예:
"FooBar.pm 은 FOO 프로토콜을 구현하고 연관된 BAR 표준을 제공하는 기능을 한다."

좋은 예:
"Foo.pm은 FOO 프로토콜의 구현한다. Bar.pm은 연관된 BAR 프로토콜을 구현한다."

이는 개발자가 단지 BAR 표준을 위한 하나의 모듈만 필요하다면, FOO와 같은 라이브러리들은 절대 설치되지 않게해야 함을 의미한다.

이름을 어떻게 지을것인가?

초기에 당신의 모듈을 위한 적당한 이름을 고려해라. 이는 사람들이 당신이 만든 모듈을 찾고 기억하는데 도움을 줄것이다. 당신의 모듈로 더욱 더 직관적으로 프로그램을 짤 수있게 할것이다.

모듈이름 정할때 아래사항들을 고려해라.

- 사실적으로 기술(모듈의 목적에 맞게 자세히 설명되는)

- 이미 존재하는 모듈과 일관된 네이밍룰을 가져라.

- 모듈의 구현이 아닌 기능성을 반영해라.

- 특히, 당신의 모듈이 위치할 곳에 이미 적당한 계층이 존재한다면 최상위 계층에 모듈명이 시작되는것을 피해라.

당신의 모듈을 publishing 하기전에 모듈이름에 대해서 modules@perl.org 에 문의해야 한다. 모듈 어플리케이션 도메인과 CPAN 네이밍 시스템을 잘 아는 사람들에게 문의해야 한다. 유사한 모듈 또는 유사한 이름의 모듈 저자에게 문의하는것도 좋은 방법이다.

모듈 디자인 및 작성

모듈을 디자인하고 코딩할때의 고려사항들

객체지향과 비객체지향

당신의 모듈은 객체지향일수도 있고 비객체지향적일 수 있고 두가지 방식 모두 가능할 수도 있다. API를 디자인할때 고려되는 각각의 테크닉에 대한 찬반양론이 있다. Damian Conway에 따르면, 당신은 객체지향 방식을 고려해야 한다.

- 시스템이 거대하거나 또는 그리 될 가능성이 많을때

- 객체가 될 명백한 구조에서 데이터가 모아질때

- 상속받아 사용할 수있는 일반적인 계층형 데이터 타입일때

- 데이터 타입에 따른 많은 연산이 필요할 때 (적당한 메소드로 다형성 구현)

- 새로운 데이터타입이 나중에 시스템으로 전달되거나 존재하는 코드에 의해 핸들링 될 필요가 있을때

- 데이터의 상호작용으로 오버로드된 연산자에 의해 재작성될때

- 시스템 컴포넌트의 구현이 시간이 지남에 따라 변할수 있을때 (따라서 캡슐화 시켜야 한다)

- 시스템 디자인이 원래 객체지향적으로 되어 있을때

- 클라이언트 코드의 상당부분이 소프트웨어에 사용될때 (구현시 수정된것으로부터 분리되어야 한다)

- When many separate operations will need to be applied to the same set of data (?)

당신의 모듈이 객체지향에 적합한지는 많은 고찰이 필요하다. 아무런 이유없이 객체지향기법을 사용하면 API는 복잡해지고 그 모듈을 사용하거나 이해하려는 일반적인 사용자는 상당한 어려움을 겪게된다.

API 디자인

당신의 interface는 일반적인 펄 프로그래머가 이해할 수 있어야 한다. 아래의 가이드라인은 당신의 API가 제대로된건지 그렇지 않은지 판단하는데 도움을 줄것이다.

간단한 기능에 간단한 루틴을 작성하라. 수많은 간단한 루틴이 몇개의 복잡한 루틴보다 더 좋다. 만약 당신의 루틴이 인자때문에 상당한 기능의 수정이 있다면 2개(그 이상으로) 분리된 루틴을 작성하는것이 그 이유이다.

결과물로부터 기능적으로 분리해라. 가능한 가장 일반적인 형태에서 결과를 리턴해라. 그리고 사용자가 그것들을 사용하는 방법을 선택할 수 있게 만들어라. 가능한 가장 일반적인 형태란 텍스트, HTML, XML, DB 쿼리 또는 사용자가 요구하는 다른 어떤 포맷에 익숙한 펄 데이터 구조이다. 만약 당신의 루틴이 어떠한 리스트(파일리스트, 데이터베이스 레코드 등)를 반복하는 것이라면 리스트 각각의 요소를 차례로 컨트롤할 수있게 하기위해 callback을 제공하는것을 고려해야 할 것이다. 그러한 예로 File::Find 모듈은 find(\&wanted, $dir)를 제공한다.

적당한 단축과 default를 제공해라. 간단한 결과를 이루기위해 남들이 하는 그대로 똑같이 모듈사용자에게 요청하지마라. 당신은 선택적으로 파라미터를 포함하거나 더욱 복잡한 루틴을 포함하거나 표준적이지 않은 기능 역시 포함할 수 있다. 만약 그들이 당신의 모듈을 사용하기 시작했을때 거의 대부분 동일한 코드라인을 가진다면 당신은 기본적인 기능을 만들었다는 것을 의미한다. 당신이 기본적인것을 사용해야하는 또 다른 좋은 지표는 대부분의 사용자들이 당신의 루틴을 같은 파라미터로 호출하는 것이다.

네이밍 관례 네이밍은 일관되어야 한다. 예를들면

display_day();
display_week();
display_year();

이 코드가

display_day();
week_display();
show_year();

이 코드보다 더 좋다. 이것은 메소드명, 파라미터명 그리고 사용자에게 보여지는 어떤 이름에도 그대로 적용된다.(대부분 그렇지 못하다)

Parameter passing 네이밍된 파라미터를 사용해라.

$obj->do_something(
    name => "wibble",
    type => "text",
    size => 1024,
);

위 처럼 해시를 사용하는게 아래처럼 네이밍되지 않은 하나의 긴 리스트보다 훨씬 코드가 쉽다.

$obj->do_something("wibble", "text", 1024);

인자가 하나라면 괜찮지만 둘,셋 또는 그 이상이되면 모듈사용자가 기억하기 어렵고 모듈제작자가 관리하기 어렵다. 만약 당신이 새로운 파라미터를 추가하고 싶다면 이전 버전과의 호환성 유지를 위해 리스트의 끝에 그것을 추가해야한다. 이는 리스트가 직관적이지 못하게 될 가능성이 크다. 또한, 많은 요소들이 undefined 이라면 메소드 호출하는 코드가 아래처럼 아름답지 못할 것이다.

$obj->do_something(undef, undef, undef, undef, undef, undef, 1024);

적당한 디폴트 파라미터를 제공해라. 사용자에게 거의 대부분 동일한 파라미터를 지정하게 만들지 마라. 해시나 해시레퍼런스로 인수를 통과할 것인지 그렇지 않을것인지의 이슈는 개인 스타일의 문제이다. 해시키의 사용은 하이픈(-)으로 시작하거나 전체를 대문자로 하는것은 소문자가 => 연산자에 의해서 정확하게 핸들링할 수 없었던 오래된 펄버전의 잔재이다. 어떤 모듈은 역사적인 이유 또는 개인적인 스타일 문제등으로 하이픈붙은 키 또는 대문자 스타일을 그대로 유지하기도 한다. 대부분의 새로운 모듈들은 간단하게 소문자 키를 사용한다. 당신이 어떠한 선택을 하던 일관성을 유지해라!

Strictness and warnings

당신의 모듈은 strict 환경에서 어떠한 경고없이 성공적으로 작동을 해야 한다. 또한 수많은 조건에서 갖가지 돌출사항이 있더라도 적절한 오류체크를 할 수 있어야 한다.

이전버전과 호환성

"stable"한 모듈들은 적어도 아주 오래된 문법을 사용한다던지 버전의 큰 변화가 없는한 이전버전과의 호환성을 깨뜨려서는 안된다.

에러처리 메시지

당신의 모듈에서 에러가 발생했을때 다음과 같이 해라.

- undefined 값을 리턴

- $Module::errstr을 세팅하거나 또는 그와 유사한 것을 세팅(errstr은 DBI 또는 다른 유명한 모듈에 사용되는 일반적인 이름; 당신이 그외 다른 어떤것을 선택할 경우 문서를 확인해라)

- warn() 또는 carp() 메시지를 STDERR로 보내라

- croak()은 당신의 모듈이 무슨일을 하는지 알 수 없을때에만 사용해라.(모듈내에서 사용할때 die()보다 croak()이 좋다. croak()은 호출자의 관점에서 그것의 에러를 리포트한다. croak(),carp() 그리고 다른 유용한 루틴을 참조하려면 Carp 모듈을 참조해라)

- 위의 대안으로는, 당신은 Error 모듈을 사용해서 exception이 떨어지게 하는걸 좋아할지도 모르겠다.

에러 핸들링을 설정하는것은 사용자에게 굉장히 유용하다. 경고메시지와 디버거메시지의 레벨을 선택하거나, 메시지 내용을 파일로 보낸다거나, 에러핸들링 루틴을 지정하는 다른 방법이나 그 밖의 다른 특징들에 대해 고려해라. 가장 일반적으로 사용되는 이러한 선택들은 기본적으로 갖추어져야 한다.

모듈 문서작업

POD (plain old documentation)

당신의 모듈은 펄개발자들을 위한 문서를 제공해야 한다. 펄에서 일반적인 기술문서를 위한 POD를 사용한다. 다른포맷에서의 추가적인 문서작업(white paper, 튜토리얼 등)을 할 때에도 POD를 사용한다. 아래 이슈들을 파악해야 한다.

- 모듈의 일반적인 개요

- 당신의 모듈이 사용될 프로그램, 범위, 목적

- public하게 access 할 수있는 메소드나 서브루틴을 기술하고 파라미터와 리턴값을 포함해라.

- 사용 예

- 더 많은 소스정보

- 저자/관리자의 메일주소

펄모듈 문서작업의 상세레벨은 일반적으로 작은 분량에서 많은 분량으로 늘어간다. SYNOPSIS 섹션은 작은 예를 포함해야 한다.(한 라인이 안될정도의 코드; 대부분 사용자에게 필요없거나 일반적이지 않은 경우는 생략) DESCRIPTION 은 일반적으로 몇개의 단락으로 나눠 모듈에 대한 전체적인 설명을 한다. 모듈의 루틴,메소드,예제 또는 보다 심오하고 중요한 내용은 하위절에서 다룬다.

당신의 모듈에 대해 좀 알고있는 사람은 "page down"키 없이도 자신의 기억을 새롭게 할 수있으면 더할나위 없이 좋을것이다. 당신의 독자들이 문서를 통해서 익혀나갈때 그들의 지식은 점차적으로 늘어갈 것이다.

펄모듈 문서의 섹션순서는 다음처럼 한다.

- 이름

- 개요

- 설명

- 관련된 더욱 자세한 내용

- 버그/경고/기타

- 저자

- 다른 참조

- 라이센스

Keep your documentation near the code it documents ("inline" documentation). Include POD for a given method right above that method's subroutine.

README, INSTALL, release notes, changelogs

당신은 모듈을 설명하는 README 파일을 포함할 수 있고 더 많은 정보를 제공할 수 있다(웹사이트,이메일을 통해서) INSTALL파일은 간단한 설치명령을 포함하고 있다. ExtUtils::MakeMaker? 모듈을 사용할 때, 다음과 같이 한다.

perl Makefile.PL
make
make test
make install

Module::Build 모듈을 사용할 때, 다음과 같이 한다.

perl Build.PL
perl Build
perl Build test
perl Build install

release note 나 changelog는 사용자에게 보여지는 모듈의 변화를 보여준다. 사용자에게 유용하다.

릴리즈시 고려해야 할 것

버전 번호

버전번호는 메이저릴리즈, 마이너릴리즈를 가리킨다. 서브 마이너 릴리즈를 가리킬 수도 있다. 메이저 릴리즈는 기능면에서 중요한 변화가 있거나 새로운 기능이 추가되었을때 적용한다. 마이너 릴리즈는 작은 기능이 추가되거나 바뀌었을때, 서브마이너 릴리즈는 기능적인 변화는 없고 문서패치와 같은 경우 적용된다.

가장 중요한 CPAN 버전의 번호부여는 다음과 같다.

1.00, 1.10, 1.11, 1.20, 1.30, 1.31, 1.32

올바른 CPAN 버전 번호는 소숫점 2자리로 표시한다. CPAN에 따르는지 그렇지않은지는 아래와 같이 확인해 볼수있다.

perl -MExtUtils::MakeMaker -le 'print MM->parse_version(shift)' 'Foo.pm'

만약, 모듈버전에 alpha나 beta를 추가는 하지만 CPAN에 리스트되지 않게 하려면 최신 정규버전 뒤에 '_'를 붙이고 숫자2개로 표시한다.(이를테면 1.20_01) 아래와 같이 하는것을 권장한다.

$VERSION = "1.12_01";
$XS_VERSION = $VERSION; # only needed if you have XS code
$VERSION = eval $VERSION;

MakeMaker?가 첫라인과 언더라인만 읽는다는 트릭을 이용해서 펄 인터프리터가 $VERSION 변수를 해석하고 문자열을 숫자로 변환한다. $VERSION을 숫자로 취급하는 이후의 연산에서 $VERSION이 숫자가 아니라는 경고 없이 사용할 수 있다.

숫자 증가없이 어떠한 릴리즈도 하지마라!(단지, 문서의 한 단어를 수정하는 것일지라도) 한 단어 문서패치라도 서브 마이너 레벨의 버전 변화를 주어야 한다.

모듈 요구사항

모듈제작자는 다른 모듈에 의존되는지 주의깊게 살펴봐야 한다. 가장 중요한것은 가능하면 안정적인 모듈을 선택하라는 것이다. 아래의 순서를 따라라.

- Core Perl 모듈

- Stable CPAN 모듈

- Unstable CPAN 모듈

- CPAN으로 부터 사용하지 않는 모듈

당신의 Makefile.PL 이나 Build.PL 에서 사전에 요구되는 다른 펄 모듈 요구버전을 명시해라. Makefile.PL 이나 Build.PL, 그리고 펄 버전 5.6.1 또는 이와 유사한 버전 모두 요구되는것을 명시해야 한다. 보다 상세한 내용은 "require" in perlfunc 의 use VERSION 섹션을 참조.

테스트

모든 모듈을 배포되기전에(make disttest를 사용해서) 테스트 되어야 한다. 테스트는 모듈을 설치하려는 사람들에게 유용해야 한다.(make test) 당신은 perl Build test와 동등한 make test를 사용하는 Module::Build를 사용한다.

이런 테스트의 중요성은 모듈의 안정성을 증가시켜준다는 것이다. 안정적이거나 광범위하게 쓰이길 원하는 모듈을 가능하면 엄격하고 꼼꼼하게 테스트를 수행해야 한다. 당신의 테스트에 많은 도움을 주는 유용한 모듈(Test::Simple, Carp::Assert, Test::Inline를 포함하는)은 당신이 작업하는 시간이나 개발 프로세스 중간에 충돌을 최소화 한다. 보다 정교한 테스트를 위한 모듈은 Test::More, Test::MockObject? 등이 있다.

패키징

모듈은 표준 패키징 툴들중 하나를 사용해서 패키징 한다. 현재 당신은 ExtUtils::MakeMaker? 와 플랫폼 독립적인 Module::Build 를 선택할 수 있다. 이들은 일관성있게 모듈을 설치하게 해준다. ExtUtils::MakeMaker? 를 사용할때 당신은 패키지를 생성하기 위해 "make dist" 를 한다. MakeMaker? 스타일의 당신의 모듈을 빌드하는데 도움을 주는 툴들이 존재한다. ExtUtils::ModuleMaker? 과 h2xs 같은게 그것들이다. perlnewmod를 참조하라.

라이센스

당신의 모듈은 라이센스를 가져야 한다. 전체 내용은 배포판에 포함된다.(라이센스의 기간이나 일반적인 것들이 없으면 당신이 그것을 포함하는것을 요구하지 마라) 만약, 당신이 라이센스 사용을 잘 모른다면 GPL과 Artistic 라이센스하에(perl 처럼) 두는것이 좋다. perlgpl과 perlartistic를 참조하라.

일반적인 함정

불필요한 일

CPAN에 이미 많은 프로그램들이 존재한다. templating 시스템을 예로 들어보자. 다른 많은 날짜와 시간 모듈이 있다. 마치 통과의례처럼 자신만의 코드를 만드는 동안 과연 내가 이것을 만들 필요가 있을지, 그렇지 않을지를 신중히 고려해라.

해야할게 너무 많은 거

당신의 모듈을 개발자들의 툴킷의 일부분이 될 수있다. 아니면 그 자체로 하나의 완성된 툴킷이 될수도 있을 것이다. 당신의 코드는 어떠한 특정 모듈보다는 하나의 단일 시스템이 될때까지 여타 가능을 추가하는 것도 괜찮다.

잘못된 문서

불량(?) 사용자를 위한 문서작업을 하는 함정에 빠지지 마라. 주 사용자는 적어도 당신의 모듈을 이해하는 개발경험이 있는 사람들이다. 그들은 당신의 모듈을 다운로드 받아 가능한 빨리 사용해보기를 원한다.

Tutorials, end-user documentation, research papers, FAQ 따위는 모듈의 메인문서로 적당하지 않다. 만약, 당신이 이런 문서작업을 하길 원한다면 My::Module::Tutorial 이나 My::Module::FAQ, 메인문서의 SEE ALSO 섹션에 링크를 제공하는 sub document에 포함시켜라.

SEE ALSO perlstyle General Perl style guide

perlnewmod How to create a new module

perlpod POD documentation

podchecker Verifies your POD's correctness

Packaging Tools ExtUtils::MakeMaker?, Module::Build

Testing tools Test::Simple, Test::Inline, Carp::Assert, Test::More, Test::MockObject?

http://pause.perl.org/ Perl Authors Upload Server. Contains links to information for module authors.

Any good book on software engineering AUTHOR Kirrily "Skud" Robert <skud@cpan.org>