-
- 1. 다른 파일을 include 하기
-
-
- 1.1. do
-
- 1.2. require
-
- 1.3. use
-
2. perldoc use 번역
-
-
- 2.1. 참고: 'use VERSION'의 사이드 이펙트
-
3. @INC 변경하기
-
-
- 3.1. 환경변수로 모듈 디렉토리 추가
-
- 3.2. 명령행 인자 -I
-
4. import, Exporter
-
-
- 4.1. %EXPORT_TAGS
-
- 4.2. 객체 지향 모듈의 경우
-
- 4.3. import 직접 구현하기
-
5. 패키지
-
-
- 5.1. package 의 스코프
-
- 5.2. __PACKAGE__ 상수
-
6. 기타
-
- 7. Comments
-
1. 다른 파일을 include 하기
@INC에 나열된 경로에서 파일을 찾아서, do가 있는 자리에서 파일의 내용을 실행. 메인 프로그램의 블록 안에 있는 것처럼 동작하나, 메인 프로그램에 있는 렉시컬 변수들은 접근하지 못한다.
리턴값
- 파일을 못 찾으면 undef반환, $! 설정
- 찾았으나 컴파일 안 되면 undef반환, $@ 설정
- 성공적으로 수행되면 마지막으로 계산한 식의 값을 반환
config 파일을 읽는 예
for $file ("/share/prog/defaults.rc",
"$ENV{HOME}/.someprogrc")
{
unless ($return = do $file) {
warn "couldn't parse $file: $@" if $@;
warn "couldn't do $file: $!" unless defined $return;
warn "couldn't run $file" unless $return;
}
}
do와 같지만, 한 번 로드한 파일을 다시 require하면 무시한다. 파일을 못 찾으면 에러.
bareword를 쓸경우는 ".pm"파일을 찾는다. "::"는 디렉토리 구분자로 변환
require Monty::Python;
require와 같지만, 프로그램이 시작되면 제일 먼저 실행한다. (컴파일 타임에)
if ($graphical) {
use MyProgram::Graphical;
} else {
use MyProgram::Text;
}
2. perldoc use 번역
use 번역 (5.14.1 기준)
use Module VERSION LIST
use Module VERSION
use Module LIST
use Module
use VERSION
지정한 모듈로부터 일부 시맨틱을 가져와 현재 패키지에 임포트한다. 일반적으로 서브루틴이나 변수들의 이름을 현재 패키지에 alias하는 형태로 이루어진다.
BEGIN { require Module; Module->import( LIST ); }
- 위와 같이 한 것과 완전히 동일하되, Module 부분이 bareword여야만 한다는 것이 다르다.
조건부로 임포트를 할 수 있다; if 참조
use VERSION
형태의 경우, VERSION은 5.006 같은 십진수 양의 소수일 수 있고 이것은 $]
와 비교되게 된다. 또는 v5.6.1과 같은 v-string일 수도 있고, 이것은 $^V
($PERL_VERSION)과 비교되게 된다. 만일 VERSION의 값이 현재 사용중인 Perl 인터프리터의 버전보다 크다면 익셉션이 발생한다; Perl은 스크립트 파일의 나머지를 해석하지 않으려 할 것이다. require는 비슷한 검사를 런타임에 하는 것과 비교된다. 반대로, no VERSION
은 명시된 버전보다 이전 버전의 Perl을 쓰기를 요구한다.
VERSION을 v5.6.1 형태로 표시하는 건 이 형태를 지원하지 않는 오래된 버전(정확히는 5.6.0이전)의 Perl에서는 잘못 해석된 에러 메시지를 내므로 피하는 게 좋다. 동일한 의미의 소수 형태를 써야 한다.
use v5.6.1;
use 5.6.1;
use 5.006_001;
이것은 오래된 버전의 펄에서 동작하지 않는 라이브러리 모듈을 use
하기 전에 현재 Perl의 버전을 체크하고자 할 때 유용하다.
또한, 명시된 펄 버전이 5.9.5 또는 그 이후 버전일 경우, use VERSION
은 feature
프라그마도 같이 로드하고 요청된 버전에서 제공하는 모든 기능을 가능하게 한다. feature 참조. 유사하게, 만일 명시된 펄 버전이 5.11.0 또는 그 이후 버전이라면, use strict
를 한 것처럼 strict 프라그마도 작동하게 된다 (strict.pm 파일이 실제로 로드되지는 않는다는 것이 다르다)
BEGIN
블록은 require
와 import
가 컴파일타임에 실행되도록 한다. require
는 모듈이 아직 메모리에 로드되지 않았다면 로드한다. import
는 내장함수가 아니라, 단지 평범하게 Module
패키지에 정적으로 메쏘드를 호출하여 그 모듈로 하여금 여러 기능을 현재 패키지에 가져오도록 하는 것이다. 모듈은 자신의 import
를 자신이 원하는 어떤 식으로든 구현할 수 있으나, 대부분의 모듈은 Exporter 모듈에 정의되어 있는 Exporter
클래스에서 상속받아 제공한다. 만일 import
메쏘드가 없을 경우 이 호출은 생략되며, 설령 AUTOLOAD 메쏘드가 있는 상태라도 마찬가지이다.
만일 모듈 패키지의 import
를 호출하고 싶지 않다면 (예를 들어 현재 패키지의 네임스페이스에 변화가 생기는 걸 막기 위해서), 명시적으로 빈 리스트를 넘겨주라:
use Module ();
이것은 정확히 다음과 동일하다:
BEGIN { require Module }
Module과 LIST 사이에 VERSION 인자가 존재한다면, use
는 클래스 모듈에 있는 VERSION 메쏘드를 호출하며, 주어진 버전값을 인자로 넘겨준다. UNIVERSAL 클래스에서 상속되는 디폴트 VERSION 메쏘드는 $Module::VERSION
변수의 값이 인자로 받은 버전보다 낮으면 경고(croak)한다.
다시 한 번, LIST를 생략하는 것(이 경우 import
가 인자 없이 호출된다)과 명시적으로 빈 리스트 ()
를 넘겨주는 것(이 경우 import
가 호출되지 않는다)을 구분하라. VERSION 다음에 쉼표가 없다는 것에 유의하라.
프라그마(컴파일러 지시자)들도 이 형태로 구현되어 있다. 현재 구현된 프라그마들은 다음과 같다:
use constant;
use diagnostics;
use integer;
use sigtrap qw(SEGV BUS);
use strict qw(subs vars refs);
use subs qw(afunc blurfl);
use warnings qw(all);
use sort qw(stable _quicksort _mergesort);
이런 pseudo-module들 중 일부는 시맨틱을 현재 블록 스코프에 임포트한다 (strict
나 integer
처럼). 보통의 모듈들이 시맨틱을 현재 패키지(파일의 끝까지 적용된다)에 임포트하는 것과 대조적이다.
use
는 컴파일타임에 적용되므로, 컴파일되는 코드의 실행흐름에 영향을 받지 않는다. 특히, use
를 조건문에서 실행되지 않을 분기(false branch)에 둔다 해도 그 use는 처리된다. 모듈이나 프라그마가 특정 조건에서만 로드되어야 한다면, if 프라그마를 사용한다:
use if $] < 5.008, "utf8";
use if WANT_WARNINGS, warnings => qw(all);
no
선언은 use
에 의해 임포트될 내용들은 unimport한다. 즉 unimport Module LIST
를 호출한다. 이 호출은 import
가 VERSION 인자를 받았을 때, LIST를 생략했을 때, 빈 LIST를 인자로 받았을 때, 메쏘드가 아예 없을 때 동작했던 방식과 동일하게 동작한다.
no integer;
no strict 'refs';
no warnings;
no VERSION
형태를 사용할 때 주의하라. 이것은 단지 현재 실행되는 버전이 인자로 준 버전보다 낮다는 걸 확인하는 용도일 뿐, use VERSION
에 의해 발생하는, 여러 feature가 사용가능하게 되는 효과를 취소하는 용도가 아니다.
perlmodlib에서 표준 모듈과 프라그마 목록을 볼 수 있다. perlrun에서, 커맨드라인에서 Perl을 실행할 때 -M
과 -m
옵션을 주어 use
기능을 사용하는 방법에 대해 알 수 있다.
2.1. 참고: 'use VERSION'의 사이드 이펙트
원문: [Watch out for side effects with `use VERSION` | The Effective Perler]
Perl 5.9.5 이전 버전까지는 use VERSION
은 단지 Perl 인터프리터의 버전을 체크하는 용도였다.
그러나 5.9.5와 그 이후 버전에서는 그 버전에 추가된 새로운 기능들을 추가하는 동작도 한다.
use 5.010
use 5.010
을 하면, 이 버전에 추가된 세 가지 기능인 say
, state
, given-which
가 임포트된다. 표면상으로는 새 버전의 perl에 새로운 키워드들이 추가됨에 따라 이전 버전에 맞춰 작성된 프로그램이 실행되지 못하게 하려는 거고, 또한 좋은 프로그래밍 철학을 받아들이도록 강요하기 위해서이기도 하다.
use 5.010;
say 'I can use Switch!';
given ($ARGV[0]) {
when( defined ) { some_sub() }
};
sub some_sub {
state $n = 0;
say "$n: got a defined argument";
}
Perl 5.010을 쓰길 강요하되 새 기능들을 사용하지 않게 하려면, feature
프라그마를 사용하여 언임포트할 수 있다:
use 5.010;
no feature;
sub say {
}
새 기능들 중 일부만 원한다면, 원하지 않는 기능들만 언임포트할 수 있다:
use 5.010;
no feature qw(say);
sub say {
}
use 5.012
Perl 5.12는 두 개의 기능이 더 추가된다. unicode_strings
는 bytes
와 locale
스코프 바깥쪽에 있는 모든 스트링을 유니코드 스트링으로 간주한다. 추가로, 자동으로 strict
를 켠다:
use 5.012;
$foo = 1;
require
를 쓰더라도 새 기능들과 strict는 켜진다:
BEGIN { require 5.012 }
$foo = 1;
어떤 이상하고도 위험한 이유가 있어서 strict를 끄고 싶다면 직접 끌 수는 있다. 그러나 그럴 경우 당신이 포장도로를 벗어났고, 렌트카 계약 사항을 위반했으며, 전기톱 살인마가 당신을 기다리고 있다는 경고를 받지 못 할 것이다
use 5.012;
no feature;
no strict;
my $foo = 1;
$fo0++;
회피 방법
오직 버전을 제한하는 것만 하고 싶다면, use
를 쓰지 않고 $]
변수의 값을 직접 체크하면 된다.
BEGIN {
die "Unsupported version"
unless $] >= 5.010 and $] < 5.011
}
이 경우는, 허용할 perl 버전의 상한값도 제한할 수 있다는 추가 장점이 있다.
요점
- Perl 5.9.5 이후부터는
use VERSION
은 새로운 기능들을 임포트한다.
-
BEGIN { require VERSION }
도 새로운 기능들을 임포트한다.
-
no feature
나 no strict
를 써서 원하지 않은 기능을 언임포트하라.
- perl 버전만을 제한하는 건
$]
변수를 사용하여 하라.
3. @INC 변경하기
use 가 먼저 실행되어 버리기 때문에, @INC값을 바꾼 후에 use를 하려고 하는 것은 불가능. 이 때는 BEGIN 서브루틴을 사용한다. BEGIN은 컴파일타임에 실행된다.
BEGIN {
push @INC, "my/module/directory";
}
use Wibble;
use lib "my/module/directory";
use Wibble;
lib 프라그마를 사용하면 코드도 더 직관적이고, 자동으로 site-dependent path들을 추가하기 때문에 권장
경로명에 변수를 사용할 수는 없다. (변수 할당은 런타임에 이뤄지므로) 이 경우는 use constant 프라그마 사용
my $LIB_DIR = '/home/gilligan/lib';
...
use lib $LIB_DIR;
use Navigation::SeatOfPants;
use constant LIB_DIR => '/home/gilligan/lib';
...
use lib LIB_DIR;
use Navigation::SeatOfPants;
펄 스크립트가 있는 경로를 기준으로 지정하고 싶다면, FindBin 모듈을 사용하여 경로를 얻어낼 수 있다.
use FindBin qw($Bin);
use lib $Bin;
use lib "$Bin/lib";
use lib "$Bin/../lib";
3.1. 환경변수로 모듈 디렉토리 추가
PERL5LIB 환경변수에 추가
export PERL5LIB=/Users/home/Ginger
3.2. 명령행 인자 -I
-I 옵션으로 추가 가능
perl -I/home/skipper/perl-lib /home/skipper/bin/get_us_home
4. import, Exporter
모듈에 정의된 서브루틴을 호출자의 패키지로 가져오기
use Wibble ("wobble", "bounce", "boing");
Wibble::import("wobble", "bounce", "boing");
import를 따로 정의해 줄 수도 있지만, 주로 Exporter 모듈을 사용한다.
모듈의 @EXPORT_OK 패키지 변수에 지정된 것들만 import가능하고, use 에 파라메터가 없을 경우는 @EXPORT에 지정된 것이 디폴트로 import된다.
package Wibble;
use warnings;
use strict;
use Exporter;
our @ISA = qw(Exporter);
our @EXPORT = qw(bounce);
our @EXPORT_OK = qw(wobble bounce boing);
sub wobble { print "wobble\n"; mine(); }
sub bounce { warn "bounce\n"; }
sub boing { die "boing!\n"; }
sub mine { print "not be exported\n"; }
1;
4.1. %EXPORT_TAGS
여러 서브루틴이나 변수를 그룹지어서 태그로 묶음. 원하는 그룹을 한번에 import할 수 있게 함. 태그 이름 앞에는 콜론을 붙임
use Fcntl qw( :flock );
자동적으로 사용가능한 태그들:
- DEFAULT - 임포트 리스트가 없을 때 임포트되는 것과 동일
태그 정의는 %EXPORT_TAGS 해쉬 변수에 한다.
- 해쉬 키는 태그 이름 (콜론 없이)
- 해쉬 값은 심볼들의 익명 배열. 이 심볼들은 @EXPORT 또는 @EXPORT_OK에 있는 것이어야 함
package Navigate::SeatOfPants;
use base qw(Exporter);
our @EXPORT = qw(guess_direction_toward);
our @EXPORT_OK = qw(
get_north_from_professor
according_to_GPS
ask_the_skipper_about
);
our %EXPORT_TAGS = (
all => [ @EXPORT, @EXPORT_OK ],
gps => [ qw( according_to_GPS ) ],
direction => [ qw(
get_north_from_professor
according_to_GPS
guess_direction_toward
ask_the_skipper_about
) ],
);
4.2. 객체 지향 모듈의 경우
일반적으로 OO모듈은 아무것도 export하지 않는다.
package My::OOModule::Base;
our @EXPORT = ( );
use base qw(Exporter);
다음 메쏘드들은 Exporter에서 특별한 용도로 사용되므로, OO모듈에서 사용할 수 없거나, 오버라이드하지 않는 게 좋다.
- export_to_level
- require_version
- export_fail
- unimport
4.3. import 직접 구현하기
import도 서브루틴이므로, 이걸 구현하여 임포트 리스트에 옵션을 받는다거나 하는 용도로 쓸 수 있다. (CGI, Test::More 등이 예)
sub import {
no strict 'refs';
my $debug = grep { $_ eq 'debug' } @_;
my( $package, $file, $line ) = caller;
warn "I was called by $package in $file\n" if $debug;
for (qw(filename basename fileparse)) {
*{$package . "::$_"} = \&$_;
}
}
5.1. package 의 스코프
package directive의 스코프는
- 다음 package 지시자가 올 때까지, 또는
- 중괄호 블럭 안에서 선언된 경우 해당 블럭의 끝까지
package Navigation;
{
package main;
sub turn_toward_heading {
.. code here ..
}
}
sub turn_toward_port {
.. code here ..
}
다음 이름들은 현재 패키지에 관계없이 main 패키지에 속한 것으로 간주된다:
- ARGV, ARGVOUT, ENV, INC, SIG, STDERR, STDIN, STDOUT
- punctuation mark variables: $_, $2, 등등
5.2. __PACKAGE__ 상수
__PACKAGE__
상수는 현재 패키지 이름이 담겨 있다. 패키지 안에서 그 패키지 이름을 반복해서 사용해야 되는 경우에 사용한다. 나중에 패키지 이름을 변경하거나, 중간의 코드만 복사해서 다른 데서 사용할 때 에러를 예방할 수 있다.
package Music::Artist;
use base 'Music::DBI';
Music::Artist->table('artist');
__PACKAGE__->table('artist');
현재 패키지 이름을 /해쉬의 키로 사용할 경우 주의해야 한다. 해쉬키 자리에 bareword가 사용될 경우 자동으로 스트링으로 취급하기 때문이다.
$hash{__PACKAGE__} = 1;
$hash{"__PACKAGE__"} = 1;
$hash{__PACKAGE__ . ""} = 1;
my $package = __PACKAGE__;
$hash{$package} = 1;
__PACKAGE__ 는 컴파일타임에 계산되며, __FILE__이나 __LINE__과 마찬가지로 스트링 안에서 interpolate되지 않는다.[1]
7. Comments
컴퓨터분류