펄 모듈 라이브러리
펄 모듈 라이브러리 (perlmodlib)
새 Perl 모듈을 어떻게 만들고, 이미 있는 모듈을 어떻게 찾아 쓰는지 알려 주는 문서예요. Perl 배포본에 번들로 들어 있는 모듈 전체 목록과, 모듈을 직접 만들 때 지켜야 할 지침들을 담고 있답니다.
출처: perlmodlib - constructing new Perl modules and finding existing ones
펄 모듈 라이브러리 (The Perl Module Library)
Perl 배포본에는 수많은 모듈이 포함되어 있어요. 아래에 설명할 것들이며 모두 *.pm으로 끝난답니다. 컴파일된 라이브러리 파일(*.so로 끝나는 것), 자동 로드될 작은 모듈 조각(*.al로 끝나는 것)도 발견할 수 있는데, 이것들은 설치 과정에서 자동 생성된 것이에요. 또 라이브러리 디렉터리에서 *.pl이나 *.ph로 끝나는 파일도 발견할 수 있어요. 이것들은 예전 프로그램이 계속 동작하도록 남겨 둔 옛 라이브러리예요. *.pl 파일은 언젠가는 표준 모듈로 변환될 것이고, h2ph로 만든 *.ph 파일은 h2xs로 만든 확장 모듈로 바뀌게 될 거예요. (*.ph 일부 값은 이미 POSIX, Errno, Fcntl 모듈을 통해 사용할 수 있어요.) 배포본의 pl2pm 파일이 변환을 도와줄 수 있지만, 기계적인 과정이라 완벽하진 않아요.
프래그마 모듈 (Pragmatic Modules)
프래그마 모듈은 컴파일러 지시어처럼 동작해요. 프로그램 컴파일에 영향을 주기 때문에 보통 use나 no 안에서만 잘 동작한답니다. 대부분은 어휘적(lexical) 범위를 가지므로, 안쪽 BLOCK에서 다음과 같이 되돌릴 수 있어요.
no integer;
no strict 'refs';
no warnings;
이 효과는 그 BLOCK이 끝날 때까지 유지돼요.
일부 프래그마는 어휘적 범위를 가져요 — 주로 $^H 힌트 변수에 영향을 주는 것들이에요. 반면 use vars, use subs처럼 현재 패키지에 영향을 주는 것들도 있어요. 이것들은 특정 파일 안에서 변수나 서브루틴을 미리 선언할 수 있게 해 주지요. 이런 선언은 선언된 파일 전체에 유효하며 no vars나 no subs로 되돌릴 수 없어요.
정의된 프래그마는 다음과 같아요 (각자 문서를 갖고 있어요).
attributes — 서브루틴/변수 속성 가져오기·설정하기
autodie — 함수들을 성공하거나 die하는 함수로 바꾸기 (어휘적 범위)
autodie::exception — autodie의 예외 객체
autodie::exception::system — 시스템 호출용 autodie 예외
autodie::hints — autodie용 힌트 제공
autodie::skip — autodie가 건너뛰어야 할 함수 지정
base — 베이스 클래스 확립 및 필드 상속
bigint — 투명한 BigInteger 지원
bignum — 투명한 BigNumber 지원
bigrat — 투명한 BigNumber/정수/유리수 지원
blib — MakeMaker로 만든 모듈 디렉터리 사용
bytes — 바이트 단위 시맨틱 강제
charnames — 문자 이름 정의/별칭
constant — Perl 상수
deprecate — Perl 코어 deprecation 정책 강제
diagnostics — 상세한 런타임 진단 제공
encoding — 스크립트 인코딩 선언 (버전 의존)
experimental — experimental 기능 활성화 방지
feature — 새 Perl 기능 활성화
fields — 클래스 필드 컴파일타임 검증
filetest — 파일 테스트 연산자 커스텀
if — 조건부 모듈 포함
integer — 정수 산술 대신 사용
less — 요청한 컴파일러 기능 줄이기
lib — 모듈의 @INC 런타임 조작
locale — 내장 함수에서 로케일 처리 사용/비활성
meta — 메타프로그래밍 지시어
mro — 메서드 해석 순서(MRO) 선택
open — Perl 기본 I/O 레이어 설정
ops — 불투명 코드 연산자 제한
overload — Perl 연산자 오버로딩
overloading — 오버로딩된 연산자 또는 bignum 함수 존재 여부 확인
parent — 베이스 클래스 확립 및 필드 상속
re — 정규식 동작/경고 수정
sort — 정렬 동작 제어
strict — 안전하지 않은 구문 제한
subs — 서브루틴 이름 미리 선언
threads — 스레드 프로그래밍 인터프리터 확장
threads::shared — 데이터를 스레드 간 공유로 표시
utf8 — 소스 파일의 유니코드/로케일 인코딩 활성화·비활성
vars — 패키지 변수 미리 선언
version — 문자열 버전 객체에 대한 심볼릭 연산자 추가
vmsish — VMS 특정 모듈 제어
warnings — 경고 출력 제어
warnings::register — 사용자 지정 경고 가져오기/등록
표준 모듈 (Standard Modules)
문서화된 표준 모듈 목록은 매우 방대해요. 대표적으로 분류하면 다음과 같아요. (전체 목록은 perldoc perlmodlib 또는 시스템의 perldoc으로 확인할 수 있어요.)
- 코어 확장: Socket, Fcntl, POSIX, B, O, Opcode, ExtUtils 계열, XSLoader, DynaLoader
- 데이터 구조/유틸리티: List::Util, Scalar::Util, Hash::Util, Tie::* 계열, Math::* 계열, Digest::*
- 파일/IO: File::* 계열, IO::* 계열, Path::, Text:: 계열 (Text::Wrap, Text::ParseWords, Text::Tabs, Text::Balanced, Text::Abbrev)
- 정규식: re, Regexp::*
- 유니코드: Unicode::Collate, Unicode::Normalize, Unicode::UCD, utf8, charnames
- 네트워크: Socket, IO::Socket::, Net:: 계열
- 테스트: Test::More, Test::Simple, Test::Harness, Test::Builder, Test2 계열, Test::Tutorial
- 시간: Time::HiRes, Time::Local, Time::Piece, Time::Seconds, Time::gmtime, Time::localtime
- 객체/클래스: UNIVERSAL, overload, fields, mro, parent, base
- 데이터베이스: DBI(별도), DBM::*, GDBM_File, SDBM_File 등
- CGI/웹: CGI, CGI::, HTTP::, URI::* (별도 모듈)
- 미래 테스트: autodie, Fatal, version
시스템에 설치된 모든 모듈을, 문서가 없거나 표준 릴리스 밖의 것까지 포함해 찾으려면 다음 명령을 쓰면 돼요 (기본 win32 셸에서는 작은따옴표 대신 큰따옴표를 써야 해요).
% perl -MFile::Find=find -MFile::Spec::Functions -Tlwe \
'find { wanted => sub { print canonpath $_ if /\.pm\z/ },
no_chdir => 1 }, @INC'
(-T는 PERL5LIB, PERLLIB, PERL_USE_UNSAFE_INC가 @INC를 채우는 걸 막기 위한 것이에요.) 그것들은 모두 설치된 자체 문서를 갖고 시스템 man(1) 명령으로 접근할 수 있을 거예요. find 프로그램이 없다면 Perl의 find2perl 프로그램을 쓸 수 있어요. man 프로그램은 있는데 모듈을 못 찾는다면 manpath를 고쳐야 해요(perl 참조). 시스템 man 명령이 없다면 perldoc 프로그램을 시도해 봐요.
또한 perldoc perllocal 명령은 시스템에 추가로 설치된 모듈 목록을 (불완전할 수 있지만) 보여 줘요. (perllocal.pod 파일은 표준 MakeMaker 설치 과정이 갱신해요.)
확장 모듈 (Extension Modules)
확장 모듈은 C(또는 Perl과 C의 혼합)로 작성돼요. 보통 필요할 때 동적으로 Perl에 로드되지만, 정적으로 링크될 수도 있어요. 지원되는 확장 모듈에는 Socket, Fcntl, POSIX가 있어요.
인기 있는 C 확장 모듈 상당수는 번들로 제공되지 않아요 (적어도 완전하진 않아요). 그 이유는 크기가 크거나, 변화가 많거나, Perl이 베타 테스트된 수많은 플랫폼에서 충분히 테스트·설정할 시간이 부족했기 때문이에요. CPAN(아래 설명)이나 Google/DuckDuckGo 같은 검색 엔진에서 찾아보시길 권해요.
CPAN
CPAN은 Comprehensive Perl Archive Network의 약자예요. 전 세계에 복제된 Perl 재료의 보고로, 문서, 스타일 가이드, 요령·함정, 비유닉스 시스템용 대체 포트, 때로는 이진 배포본까지 포함해요. CPAN 검색 엔진은 https://www.cpan.org/ 에서 찾을 수 있어요.
가장 중요하게, CPAN에는 대략 수천 개의 비번들 모듈이 있으며 일부는 빌드에 C 컴파일러가 필요해요. 모듈의 주요 분류는:
- 언어 확장 및 문서 도구
- 개발 지원
- 운영체제 인터페이스
- 네트워킹, 장치 제어(모뎀) 및 프로세스 간 통신
- 데이터 타입 및 데이터 타입 유틸리티
- 데이터베이스 인터페이스
- 사용자 인터페이스
- 다른 프로그래밍 언어로의 인터페이스/에뮬레이션
- 파일 이름, 파일 시스템 및 파일 잠금
- 문자열 처리, 언어 텍스트 처리, 파싱 및 검색
- 옵션·인자·파라미터·설정 파일 처리
- 국제화와 로케일
- 인증, 보안, 암호화
- 월드 와이드 웹, HTML, HTTP, CGI, MIME
- 서버 및 데몬 유틸리티
- 아카이빙 및 압축
- 이미지, 픽스맵·비트맵 처리, 드로잉, 그래프
- 메일 및 유즈넷 뉴스
- 제어 흐름 유틸리티 (콜백·예외 등)
- 파일 핸들 및 입출력 스트림 유틸리티
- 기타 모듈
CPAN은 https://www.cpan.org/ 에서 확인할 수 있어요.
모듈: 생성, 사용, 남용 (Modules: Creation, Use, and Abuse)
(이 절은 Tim Bunce의 modules 파일에서 직접 가져온 거예요.)
Perl은 package를 이용해 클래스를 구현하지만, package의 존재가 클래스의 존재를 의미하진 않아요. package는 그냥 이름공간(namespace)이에요. 클래스는 메서드로 사용될 수 있는 서브루틴을 제공하는 package예요. 메서드는 첫 번째 인자로 package의 이름("static" 메서드) 또는 어떤 것의 참조("virtual" 메서드)를 기대하는 서브루틴일 뿐이에요.
모듈은 (관례상) 이름이 같은 클래스(.pm을 뺀 이름)를 제공하는 파일이에요. 그리고 그 클래스에는, 내보낸 심볼을 가져오기 위해 호출할 수 있는 import 메서드가 있어요. 이 모듈은 일부 메서드를 동적 C/C++ 객체를 로드해 구현할 수 있는데, 모듈 사용자에게는 완전히 투명해야 해요. 마찬가지로 모듈이 필요할 때 서브루틴 정의를 끌어오는 AUTOLOAD 함수를 설정할 수도 있는데 이것도 투명해요. *.pm 파일만 존재하면 돼요. AUTOLOAD 메커니즘에 대해서는 perlsub, perlobj, AutoLoader를 참조하세요.
모듈 생성 지침 (Guidelines for Module Creation)
-
비슷한 모듈이 이미 어떤 형태로 존재하나요? 있다면 기존 모듈을 그대로 재사용하거나, 유용한 기능을 새 클래스로 상속받아 재사용하세요. 실용적이지 않다면 모듈 저자들과 협력해 기존 모듈의 기능을 확장·향상하세요. 예: perl4의 커맨드라인 옵션 처리 패키지 다수.
-
새 모듈이 확장·재사용하기 쉽도록 설계하세요.
use warnings;(또는use warnings qw(...);)를 쓰세요. 경고가 덜 필요한 코드 블록에는no warnings qw(...);를 추가할 수 있다는 걸 기억하세요.
bless된 참조를 쓰세요. bless의 두 인자 형식을 사용해 생성자의 첫 파라미터로 주어진 클래스 이름에 bless하세요.
sub new {
my $class = shift;
return bless {}, $class;
}
static 또는 virtual 메서드로 모두 쓰이도록 하려면 이렇게 해도 돼요.
sub new {
my $self = shift;
my $class = ref($self)||$self;
return bless {}, $class;
}
배열은 참조로 넘겨 나중에 파라미터를 추가할 수 있게 하세요 (더 빠르기도 해요). 적절한 곳에서 함수를 메서드로 변환하세요. 큰 메서드는 더 작고 유연한 것으로 나누세요. 적절하다면 다른 모듈에서 메서드를 상속받으세요.
die "Invalid" unless ref $ref eq 'FOO' 같은 클래스 이름 테스트는 피하세요. 일반적으로 eq 'FOO' 부분을 그냥 지워도 전혀 문제없어요. 객체가 스스로 알아서 관리하게 하세요! 하드코딩된 클래스 이름은 최대한 피하세요.
@ISA=qw(... Class ...)와 $r->func()로 동작하는데 $r->Class::func()를 쓰는 건 피하세요.
잘 안 쓰거나 새로 추가된 함수가 그걸 안 쓰는 프로그램에 부담이 되지 않도록 autosplit을 쓰세요. 모듈의 __END__ 뒤에 테스트 함수를 추가하되 AutoSplit을 쓰거나 다음처럼 하세요.
eval join('',<main::DATA>) || die $@ unless caller();
모듈이 '빈 서브클래스(empty subclass)' 테스트를 통과하나요? @SUBCLASS::ISA = qw(YOURCLASS);라고 한다면 애플리케이션이 YOURCLASS를 쓰는 것과 똑같이 SUBCLASS를 쓸 수 있어야 해요. 예를 들어 $obj = YOURCLASS->new();를 $obj = SUBCLASS->new();로 바꿔도 여전히 동작하나요?
package에 상태 정보를 유지하지 마세요. 다른 package들이 여러분 것을 사용하기 어려워져요. 상태 정보는 객체에 보관하세요.
항상 -w를 쓰세요. use strict;(또는 use strict qw(...);)를 쓰세요. 덜 엄격한 코드 블록에는 no strict qw(...);를 추가할 수 있다는 걸 기억하세요.
perlstyle의 지침을 따르세요.
- 간단한 스타일 지침. 단어를 밑줄로 구분하세요.
$var_names_like_this가$VarNamesLikeThis보다 읽기 쉬워요.VAR_NAMES_LIKE_THIS와 일관되게 동작하는 단순한 규칙이에요. package/모듈 이름은 예외예요. Perl은 소문자 모듈 이름을 integer, strict 같은 '프래그마' 모듈로 비공식 예약해요. 다른 모듈은 보통 대문자로 시작하고 밑줄 없는 혼합 대소문자를 써요 (짧고 이식 가능해야 해요).
변수의 범위나 성격을 나타내는 데 대소문자를 쓰면 도움이 돼요:
$ALL_CAPS_HERE constants only (beware clashes with Perl vars)
$Some_Caps_Here package-wide global/static
$no_caps_here function scope my() or local() variables
함수·메서드 이름은 전부 소문자가 가장 좋아요. 예: $obj->as_string().
정의한 package 밖에서 쓰면 안 되는 변수·함수임을 나타내려면 앞 밑줄을 써요.
-
무엇을 내보낼지 선택하세요. 메서드 이름은 절대 내보내지 마세요! 좋은 이유 없이 기본적으로 다른 것을 내보내지 마세요! export는 모듈 사용자의 이름공간을 오염시켜요. 내보내야 한다면 @EXPORT보다 @EXPORT_OK를 쓰고, 이름 충돌 위험을 줄이기 위해 짧거나 흔한 이름을 피하세요. 내보내지 않은 것은
ModuleName::item_name(또는$blessed_ref->method) 문법으로 바깥에서 접근할 수 있어요. 관례상 앞 밑줄로 '내부', 즉 공개용이 아님을 알려줄 수 있어요. 객체지향을 지향하는 모듈이면 아무것도 내보내지 마세요. 함수 모음일 뿐이면 @EXPORT_OK를 쓰고 @EXPORT는 주의해서 쓰세요. -
모듈 이름을 선택하세요. 가능한 한 서술적이고 정확하며 완전하게. 모호함 위험을 피하세요. 항상 두 개 이상의 온전한 단어를 써 보세요. 이름은 '어떻게'가 아니라 '무엇이 특별한지'를 반영해야 해요. 모듈을 비공식적으로 묶거나 분류하려면 중첩 이름을 쓰세요. 중첩 이름이 없는 모듈에는 매우 좋은 이유가 있어야 해요. 모듈 이름은 대문자로 시작해야 해요. Sort라는 모듈 57개가 있으면 아무도 편하지 않아요. 관련 모듈/클래스 제품군을 개발한다면 공통 접두사를 가진 중첩 클래스를 쓰는 게 좋아요 (Xyz::Control, Xyz::View, Xyz::Model 등) — 이름공간 충돌을 피할 수 있어요. 공개되지 않을 사내·프로젝트 특화 모듈이라면 예약된
Local::*범주를 쓰거나Foo_Corp::*처럼 밑줄이 포함된 범주 이름을 써서 미래의 공개 모듈과 충돌하지 않게 하세요. 이식성을 위해 모듈 이름의 각 구성요소는 11자로 제한해야 해요. MS-DOS에서 쓰인다면 각각 앞 8자가 고유하도록 하세요. 추가 지침은 https://pause.perl.org/pause/query?ACTION=pause_namingmodules 를 참조하세요. -
제대로 했나요? 올바른 결정을 내렸는지, 나중에 문제를 일으킬 인터페이스 설계는 아닌지 아는 가장 좋은 방법은 아는 사람에게 물어보는 거예요.
module-authors메일링 리스트가 유용해요. 모듈의 목적과 인터페이스를 짧게 요약해 올리면 돼요. 완성 시점을 못 정해도 올리는 걸 망설이지 마세요 — 메시지에 그냥 그렇게 적어요. -
README와 추가 파일. 개발자는 보통 소프트웨어를 철저히 문서화해요. 충분한 시간이 없다면 최소한 다음을 담은 README 파일을 제공하세요: 모듈 설명, 저작권 고지, 전제조건, 빌드 방법(Makefile.PL 변경 등), 설치 방법, 이번 릴리스의 최근 변경(특히 비호환성), 향후 계획. README가 너무 커지면 INSTALL, Copying, ToDo 등으로 나누세요.
-
저작권 고지를 추가하세요. 라이선스 선택은 개인 결정이에요. Perl은 예를 들어 GNU GPL과 Artistic License 두 종류로 제공돼요. 개인적 추천은 이렇게 간단히 서술하는 거예요:
Copyright (c) 1995 Your Name. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
이 문구는 최소한 README 파일에는 있어야 해요. Copyright 외의 다른 단어도 함께 포함하세요.
-
모듈에 버전/릴리스 번호를 부여하세요. Exporter와 MakeMaker와 완전히 호환되려면 버전 번호를
my가 아닌 패키지 변수$VERSION에 저장해야 해요. 소수점 뒤에 최소 두 자리(즉, 1/100 단위)가 있는 양의 부동소수점이어야 해요. 예:$VERSION = "0.01". "1.3.2" 스타일 버전은 쓰지 마세요. 번호를 가져오는 함수·메서드를 추가하면 편리해요. 릴리스 공지와 아카이브 파일 이름(ModuleName-1.02.tar.Z)에 사용하세요. -
모듈을 릴리스·배포하는 방법. 가능하면 CPAN에 모듈을 등록하세요. https://www.cpan.org/modules/04pause.html 의 지침을 따르고 https://pause.perl.org/ 에 업로드한 뒤 module-authors에 알리세요. 그러면 누구나 Perl에 포함된
cpan도구로 모듈을 설치할 수 있어요. WWW 인터페이스를 쓰면 업로드 서버가 여러분의 ftp/WWW 사이트에서 CPAN의 여러분 디렉터리로 모듈을 미러링하게 할 수 있어요! -
릴리스된 모듈을 변경할 때 주의하세요. 항상 이전 릴리스 버전과의 호환성을 유지하도록 노력하세요. 그렇지 않으면 사람들이 의존한다면 예전 동작으로 되돌릴 메커니즘을 추가하고, 비호환 변경을 문서화하세요.
Perl 4 라이브러리 스크립트를 모듈로 변환하는 지침
- 아무것도 변환할 필요는 없어요. 고장 나지 않았으면 고치지 마세요! Perl 4 라이브러리 스크립트는 계속 문제없이 동작해야 해요. 큰따옴표 문자열 안의 비-배열
@를 이스케이프하는 같은 사소한 변경은 필요할 수 있지만, 그걸 위해.pl파일을 모듈로 변환할 필요는 없어요. - 영향을 고려하세요. 스크립트를 모듈로 변환하면 그 스크립트를 쓰는 모든 Perl 애플리케이션을 (약간) 바꿔야 해요. 동시에 다른 변경도 계획하지 않는 한 그만한 가치가 있나요?
- 기회를 최대한 활용하세요. 스크립트를 모듈로 변환한다면 인터페이스를 재설계할 기회로 삼으세요. 위의 모듈 생성 지침이 고려할 문제를 많이 담고 있어요.
- pl2pm 유틸리티로 시작하세요.
*.pl파일(파라미터로 제공)을 읽어 대응하는*.pm파일을 써 줘요. pl2pm은 다음을 해요: 표준 모듈 프롤로그 줄 추가, package 지정자를'에서::로 변환,die(...)를croak(...)로 변환, 기타 사소한 변경. 기계적 과정이라 완벽하지 않으니 변환 코드, 특히 package 문장을 주의 깊게 확인해야 해요. 새.pm이 동작할 때까지 원본.pl을 지우지 마세요!
애플리케이션 코드 재사용 지침
- 완전한 애플리케이션은 펄 모듈 라이브러리에 속하는 경우가 드물어요.
- 많은 애플리케이션이 재사용할 수 있는 Perl 코드를 일부 담고 있어요.