Perl 미리 정의된 변수
Perl 미리 정의된 변수
이 문서는 Perl의 미리 정의된 특수 변수(predefined variables) 전부를 다뤄요. Perl에는 이름에 특별한 의미를 가진 변수들이 많아서, 이 문서가 그 전체를 정리해 줘요.
본문
변수 이름의 문법 (The Syntax of Variable Names)
Perl의 변수 이름은 여러 형식을 가질 수 있어요. 보통 글자나 밑줄로 시작해야 하며, 그 경우 아무리 길어도 되고(내부 한도 251자) 글자, 숫자, 밑줄, 또는 특별한 시퀀스 ::나 '를 포함할 수 있어요. 이 경우 마지막 ::나 ' 앞의 부분은 패키지 한정자(package qualifier) 로 간주돼요. perlmod를 보세요. ASCII가 아닌 유니코드 글자는 \"use utf8\"이 적용되지 않는 한 글자로 간주되지 않으며, 좀 더 복잡한 규칙이 적용돼요. 자세한 내용은 perldata의 "식별자 파싱"을 보세요.
Perl 변수 이름은 숫자 시퀀스, 단일 구두점 문자, 또는 두 문자 시퀀스일 수도 있어요: ^(caret 또는 CIRCUMFLEX ACCENT) 다음에 [][A-Z^_?\\] 중 아무 문자 하나. 이 이름들은 모두 Perl이 특수 용도로 예약해요. 예를 들어 숫자로만 된 이름은 정규식 매치 후 역참조(backreference)로 캡처된 데이터를 담는 데 쓰여요.
Perl v5.6.0부터 변수 이름은 caret이 앞에 붙은 영숫자 문자열일 수도 있어요. 이것들은 모두 ${^Foo}처럼 중괄호를 쓴 구분 형태(demarcated form)로 써야 해요. 중괄호는 선택 사항이 아니에요. ${^Foo}는 이름이 컨트롤-F 뒤에 o 두 개로 간주되는 스칼라 변수를 나타내요. (변수 이름을 쓰거나 배열·해시의 요소에 접근을 지정하는 이 형태에 대한 자세한 정보는 perldata의 "중괄호를 쓴 구분 변수 이름"을 보세요.) ^_(caret-밑줄)로 시작하는 것들을 제외하면 이 변수들은 Perl의 향후 특수 용도로 예약돼요. ^_로 시작하는 이름은 어떤 향후 Perl 버전에서도 특별한 의미를 얻지 않을 거예요. 그래서 그런 이름은 프로그램에서 안전하게 쓸 수 있어요. 단, $^_ 자체 는 예약되어 있어요.
이 타입의 변수의 첨자를 보간할 때도 구분 형태를 반드시 써야 한다는 점을 유의하세요. 예를 들어 큰따옴표 문자열 안에서 @{^CAPTURE} 변수의 첫 번째 요소에 접근하려면 \"${^CAPTURE[0]}\"이라고 써야 하고, \"${^CAPTURE}[0]\"이 아니다 — 후자는 ${^CAPTURE}라는 이름의 스칼라 변수를 참조하는 뜻이지, 정규식 엔진이 채우는 마법의 @{^CAPTURE} 배열의 인덱스 0이 아니에요.
숫자나 구두점 문자로 시작하는 Perl 식별자는 package 선언의 효과에서 면제되며 항상 패키지 main에 강제로 들어가요. strict 'vars' 오류에서도 면제돼요. 몇몇 다른 이름들도 이런 식으로 면제돼요.
ENV STDIN
INC STDOUT
ARGV STDERR
ARGVOUT
SIG
특히 특수 ${^_XYZ} 변수는 현재 스코프에 어떤 package 선언이 있든 관계없이 항상 패키지 main에 있는 것으로 간주돼요.
특수 변수 (SPECIAL VARIABLES)
다음 이름들은 Perl에 특별한 의미를 가져요. 대부분의 구두점 이름은 합리적인 니모닉이나 셸에서의 유사체가 있어요. 그래도 긴 변수 이름을 쓰고 싶다면 프로그램 맨 위에 그냥 이렇게 말하면 돼요.
use English;
이것은 현재 패키지의 모든 짧은 이름을 긴 이름에 별칭해요. 어떤 것들은 보통 awk에서 빌린 중간 이름도 있어요. 자세한 내용은 English를 보세요.
계속하기 전에 변수의 정렬 순서를 유의하세요. 일반적으로 우리는 대소문자 무시, 거의 사전순으로 변수를 먼저 나열해요(${^UNICODE}나 $^T처럼 단어 앞의 {나 ^는 무시하며), 단 $_와 @_는 맨 위로 올라가요. 같은 식별자를 가진 변수에 대해서는 스칼라, 배열, 해시, bareword 순으로 나열해요.
일반 변수 (General Variables)
$\_ — 기본 입력이자 패턴 검색 공간이에요. 다음 쌍들은 동등해요.
while (<>) {...} # equivalent only in while!
while (defined($_ = <>)) {...}
/^Subject:/
$_ =~ /^Subject:/
tr/a-z/A-Z/
$_ =~ tr/a-z/A-Z/
chomp
chomp($_)
Perl이 당신이 쓰지 않아도 $_를 가정하는 곳들이 여기 있어요.
-
다음 함수들은
$_를 기본 인자로 써요: abs, alarm, chomp, chop, chr, chroot, cos, defined, eval, evalbytes, exp, fc, glob, hex, int, lc, lcfirst, length, log, lstat, mkdir, oct, ord, pos, print, printf, quotemeta, readlink, readpipe, ref, require, reverse(스칼라 문맥에서만), rmdir, say, sin, split(두 번째 인자), sqrt, stat, study, uc, ucfirst, unlink, unpack. -
기본값이 STDIN인
-t을 제외한 모든 파일 테스트(-f,-d). perlfunc의 "-X"를 보세요. -
=~연산자 없이 쓰는 패턴 매칭 연산m//,s///,tr///(일명y///). -
다른 변수가 주어지지 않을 때
foreach루프의 기본 반복 변수. -
grep()과map()함수의 암시적 반복 변수. -
given()의 암시적 변수. -
<FH>,readline,readdir또는each연산의 결과가while테스트의 유일한 기준으로 그 자체로 테스트될 때, 다음 값이나 입력 레코드를 넣을 기본 위치.while테스트 밖에서는 이것이 일어나지 않아요.
$_는 전역 변수예요.
하지만 perl v5.10.0과 v5.24.0 사이에서는 my $_라고 써서 어휘적으로 쓸 수 있었어요. 같은 스코프에서 $_가 전역 $_를 가리키게 하는 것은 our $_로 가능했죠. 이 실험적 기능은 제거됐고 이제 치명적 오류이지만, 오래된 코드에서 만날 수는 있어요.
니모닉: 밑줄은 특정 연산에서 이해된다.
@\_ — 서브루틴 안에서 배열 @_는 그 서브루틴에 전달된 매개변수를 담아요. 서브루틴 안에서 @_는 배열 연산자 pop과 shift의 기본 배열이에요. perlsub을 보세요.
$" — 배열이나 배열 슬라이스가 큰따옴표 문자열이나 /.../ 같은 비슷한 문맥에 보간될 때, 요소들은 이 값으로 구분돼요. 기본값은 공백이에요. 예를 들어 이렇게:
print "The array is: @array\n";
는 이렇게와 동등해요.
print "The array is: " . join($", @array) . "\n";
니모닉: 큰따옴표 문맥에서 동작한다.
$$ — 이 스크립트를 실행하는 Perl의 프로세스 번호예요. 이 변수를 설정할 수 는 있지만 일반적으로 권장되진 않아요. 테스트 목적으로는 매우 귀중할 수 있지만요. fork() 호출을 가로질러 자동으로 리셋돼요.
Linux와 Debian GNU/kFreeBSD 사용자 참고: Perl v5.16.0 이전의 perl은 Linux 시스템에서 POSIX 스레드의 부분적 구현인 LinuxThreads를 사용해 POSIX 의미론을 모방했어요. 이후 Native POSIX Thread Library(NPTL)로 대체됐죠.
LinuxThreads는 이제 Linux에서 구식이며, 이렇게 getpid()를 캐싱하는 것은 perl 임베딩을 불필요하게 복잡하게 만들었어요(값 $$를 수동으로 갱신해야 했으니까요). 그래서 이제 $$와 getppid()는 항상 기본 C 라이브러리와 같은 값을 반환해요.
Debian GNU/kFreeBSD 시스템도 6.0 릴리스까지 LinuxThreads를 썼지만, 그 뒤로 POSIX와 비슷한 FreeBSD 스레드 의미론으로 옮겨갔어요.
시스템이 이 차이의 영향을 받는지 보려면 getconf GNU_LIBPTHREAD_VERSION | grep -q NPTL이 거짓 값을 반환하는지 확인하세요. NPTL 스레드는 POSIX 의미론을 보존해요.
니모닉: 셸과 같다.
$0 — 실행 중인 프로그램의 이름을 담아요.
일부(전부는 아닌) 운영 체제에서 $0에 할당하면 ps 프로그램이 보는 인자 영역을 수정해요. 일부 플랫폼에서는 변경 사항을 보려면 특별한 ps 옵션을 쓰거나 다른 ps를 써야 할 수도 있어요. $0 수정은 실행 중인 프로그램을 숨기는 것보다 현재 프로그램 상태를 나타내는 방법으로 더 유용해요.
$0의 최대 길이에는 플랫폼별 제한이 있다는 점을 유의하세요. 가장 극단적인 경우 원래 $0이 차지하는 공간으로 제한될 수 있어요.
일부 플랫폼에서는 ps가 보여 주는 수정된 이름 뒤에 공백 문자 같은 임의의 패딩이 있을 수 있어요. 일부 플랫폼에서는 이 패딩이 인자 영역의 원래 길이까지 쭉 늘어날 수 있어요(예: Linux 2.2의 경우가 그래요).
BSD 사용자 참고: $0 설정은 ps(1) 출력에서 "perl"을 완전히 제거하지 않아요. 예를 들어 $0을 \"foobar\"로 설정하면 \"perl: foobar (perl)\" 같은 결과가 나올 수 있어요("perl: " 접두사와 " (perl)" 접미사 둘 다 보이는지는 정확한 BSD 변형과 버전에 달려 있어요). 이것은 운영 체제 기능이라 Perl이 어쩔 수 없어요.
멀티스레드 스크립트에서 Perl은 스레드들을 조정해서 어떤 스레드든 자기 $0 사본을 수정할 수 있고, 그 변경이 ps(1)에 보이게 돼요(운영 체제가 협조한다고 가정하면). 다른 스레드들이 보는 $0의 관점은 자기 사본을 갖고 있으므로 바뀌지 않는다는 점을 유의하세요.
프로그램이 -e나 -E 스위치로 perl에 주어졌다면, $0은 문자열 \"-e\"를 담아요.
v5.14.0부터 Linux에서 레거시 프로세스 이름이 prctl(2)로 설정돼요. perl이 버전 4.000부터 해 온 것처럼 argv[0]으로 POSIX 이름을 변경하는 것에 더해서요. 이제 ps, top, killall 같은 레거시 프로세스 이름을 읽는 시스템 유틸리티들은 $0에 할당할 때 설정한 이름을 인식해요. 제공한 문자열은 16바이트에서 잘리는데, 이것은 Linux가 부과하는 제한이에요.
와이드 문자는 $0 값에 유효하지 않아요. 하지만 역사적 이유로 Perl은 그것들을 받아들이고 UTF-8로 인코딩해요. 이때 와이드 문자 경고가 발생해요.
니모닉: sh와 ksh와 같다.
$( — 이 프로세스의 실질 gid(real gid)예요. 여러 그룹에 동시에 속함을 지원하는 머신이라면, 당신이 속한 그룹의 공백 구분 목록을 줘요. 첫 번째 숫자는 getgid()가 반환하는 것이고, 나머지는 getgroups()가 반환하는 것으로, 그중 하나는 첫 번째 숫자와 같을 수 있어요.
하지만 $(에 할당된 값은 실질 gid를 설정하는 데 쓰이는 단일 숫자여야 해요. 그래서 $(가 주는 값은 0을 더하는 등 숫자로 강제하지 않고는 $(에 다시 할당하면 안 돼요. 이것은 유효 gid($))가 리스트를 받는 것과 다르다는 점을 유의하세요.
POSIX::setgid()로 실질 gid와 유효 gid 둘 다 동시에 바꿀 수 있어요. $(에 대한 변경은 변경을 시도한 후 가능한 오류를 감지하기 위해 $!를 확인해야 해요.
니모닉: 괄호는 것들을 그룹화 하는 데 쓰인다. setgid로 실행 중이라면 실질 gid는 당신이 떠난 그룹이다.
$) — 이 프로세스의 유효 gid(효과적 gid)예요. 여러 그룹에 동시에 속함을 지원하는 머신이라면, 당신이 속한 그룹의 공백 구분 목록을 줘요. 첫 번째 숫자는 getegid()가 반환하는 것이고, 나머지는 getgroups()가 반환하는 것으로, 그중 하나는 첫 번째 숫자와 같을 수 있어요.
비슷하게 $)에 할당된 값도 공백 구분 숫자 목록이어야 해요. 첫 번째 숫자가 유효 gid를 설정하고, 나머지(있으면)는 setgroups()에 전달돼요. setgroups()에 빈 리스트의 효과를 얻으려면 새 유효 gid를 그냥 반복하면 돼요. 즉 유효 gid 5를 강제하고 사실상 빈 setgroups() 목록을 만들려면 $) = \"5 5\"라고 하세요.
POSIX::setgid()(단일 숫자 인자만 사용)로 유효 gid와 실질 gid 둘 다 동시에 바꿀 수 있어요. $)에 대한 변경은 변경을 시도한 후 가능한 오류를 감지하기 위해 $!를 확인해야 해요.
$<, $>, $(와 $)는 대응하는 set\[re\]\[ug\]id() 루틴을 지원하는 머신에서만 설정할 수 있어요. $(와 $)는 setregid()를 지원하는 머신에서만 서로 바꿀 수 있어요.
니모닉: 괄호는 것들을 그룹화 하는 데 쓰인다. setgid로 실행 중이라면 유효 gid는 당신에게 맞는 그룹이다.
$< — 이 프로세스의 실질 uid(real uid)예요. POSIX::setuid()로 실질 uid와 유효 uid 둘 다 동시에 바꿀 수 있어요. $<에 대한 변경은 시스템 호출을 필요로 하므로, 변경을 시도한 후 $!를 확인해 가능한 오류를 감지하세요.
니모닉: setuid로 실행 중이라면 그것은 당신이 왔던 uid다.
$> — 이 프로세스의 유효 uid(효과적 uid)예요. 예를 들어:
$< = $>; # set real to effective uid
($<, $>) = ($>, $<); # swap real and effective uids
POSIX::setuid()로 유효 uid와 실질 uid 둘 다 동시에 바꿀 수 있어요. $>에 대한 변경은 변경을 시도한 후 $!를 확인해 가능한 오류를 감지해야 해요.
$<와 $>는 setreuid()를 지원하는 머신에서만 서로 바꿀 수 있어요.
니모닉: setuid로 실행 중이라면 그것은 당신이 향한 uid다.
$; — 다차원 배열 에뮬레이션을 위한 첨자 구분자예요. 해시 요소를 이렇게 참조하면:
$foo{$x, $y, $z}
실제로는 이걸 의미해요.
$foo{join($;, $x, $y, $z)}
하지만 이것은 넣지 마세요:
@foo{$x, $y, $z} # a slice--note the @
이것은 이걸 의미하니까요.
($foo{$x}, $foo{$y}, $foo{$z})
기본값은 "\\034"로 awk의 SUBSEP과 같아요. 키가 이진 데이터를 담고 있으면 $;에 안전한 값이 없을 수도 있어요.
perllol에 설명된 "진짜" 다차원 배열을 쓰는 걸 고려하세요.
니모닉: 쉼표(문법적 첨자 구분자)는 반-세미콜론이다.
$a, $b — sort()를 쓸 때의 특수 패키지 변수예요. perlfunc의 "sort"를 보세요. 이 특수성 때문에 $a와 $b는 strict 'vars' 프래그마를 쓸 때조차 (use vars나 our()로) 선언할 필요가 없어요. sort() 비교 블록이나 함수에서 쓸 수 있길 원하면 my $a나 my $b로 어휘화하지 마세요.
%ENV — 해시 %ENV는 현재 환경을 담아요. ENV에 값을 설정하면 이후 fork()해서 만들어내는 어떤 자식 프로세스의 환경도 바뀌어요.
v5.18.0부터 %ENV에 저장된 키와 값 모두 문자열화돼요.
my $foo = 1;
$ENV{'bar'} = \$foo;
if ( ref $ENV{'bar'} ) {
say "Pre 5.18.0 Behaviour";
} else {
say "Post 5.18.0 Behaviour";
}
이전에는 자식 프로세스만 문자열화된 값을 받았어요.
my $foo = 1;
$ENV{'bar'} = \$foo;
# Always printed 'non ref'
system($^X, '-e',
q/print ( ref $ENV{'bar'} ? 'ref' : 'non ref' ) /);
이것은 외부 프로세스와 임의의 데이터 구조를 진짜로 공유할 수 없기 때문에 생겨요.
$] — Perl 인터프리터의 개정, 버전, 하위버전을 5.XXXYYY 형태의 십진수로 나타낸 것이에요. 여기서 XXX는 버전 / 1e3, YYY는 하위버전 / 1e6이에요. 예를 들어 Perl v5.10.1은 "5.010001"이 돼요.
이 변수는 스크립트를 실행하는 Perl 인터프리터가 올바른 버전 범위에 있는지 판단하는 데 쓸 수 있어요.
warn "No PerlIO!\n" if "$]" < 5.008;
$]를 비교할 때는 숫자 비교 연산자를 써야 하지만, 원래 숫자 값이 부정확할 수 있는 문제를 피하려면 먼저 문자열화해야 해요.
실행 중인 Perl 인터프리터가 너무 오래됐을 때 실패하는 편리한 방법으로 use VERSION과 require VERSION 문서도 보세요.
보다 유연한 문자열 비교를 허용하는 version 객체로 Perl 버전을 나타내는 "$^V"를 보세요.
$]가 $^V보다 가진 주요 장점은 어떤 Perl 버전에서든 똑같이 동작한다는 거예요. 단점은 다른 형식의 버전(예: 리터럴 v-문자열, "v1.2.3", version 객체)과 쉽게 비교할 수 없고, 숫자 비교가 이진 부동소수점 표현의 영향을 받는다는 거예요. 숫자 리터럴 버전 검사에는 좋지만, 건전성 검사되지 않은 변수와 비교하기엔 나빠요.
$OLD_PERL_VERSION 형태는 역사적 이유로 Perl v5.20.0에 추가됐지만 사용은 권장되지 않아요. ($]을 쓰는 이유가 오래된 perl에서 코드를 실행하려는 것이라면 $OLD_PERL_VERSION로 부르는 것은 자가당착적이에요.)
니모닉: 이 perl 버전이 올바른 대괄호에 있나?
$^F — 최대 시스템 파일 디스크립터로, 보통 2예요. 시스템 파일 디스크립터는 exec()된 프로세스에 전달되지만, 더 높은 파일 디스크립터는 전달되지 않아요. 또한 open() 중에 시스템 파일 디스크립터는 open()이 실패해도 보존돼요(일반 파일 디스크립터는 open()을 시도하기 전에 닫혀요). 파일 디스크립터의 close-on-exec 상태는 해당 파일, 파이프, 소켓이 열렸을 때의 $^F 값에 따라 결정되지, exec() 시점이 아니에요.
@F — 배열 @F는 autosplit 모드가 켜져 있을 때 읽힌 각 줄의 필드를 담아요. -a 스위치에 대해 perlrun을 보세요. 이 배열은 패키지 특정적이며, strict 'vars' 아래에서 패키지 main이 아니라면 선언하거나 전체 패키지 이름을 줘야 해요.
@INC — 배열 @INC는 do EXPR, require, use 구성이 라이브러리 파일을 찾는 위치들의 목록을 담아요. 처음에는 -I 명령줄 스위치의 인자들로 시작하고, 뒤이어 기본 Perl 라이브러리(아마 /usr/local/lib/perl)로 구성돼요. Perl 5.26 이전에는 현재 디렉터리를 나타내는 .이 @INC에 포함됐었는데, 제거됐어요. 이 동작 변경은 PERL_USE_UNSAFE_INC에 문서화되어 있고, .을 @INC에 다시 추가하는 것은 권장되지 않아요. 런타임에 @INC를 수정해야 한다면 use lib 프래그마를 써서 머신 의존 라이브러리도 제대로 로드되게 해야 해요.
use lib '/mypath/libdir/';
use SomeMod;
파일 포함 시스템에 훅(hook)을 넣으려면 @INC에 직접 Perl 코드를 넣을 수도 있어요. 그 훅들은 서브루틴 참조, 배열 참조, 또는 bless된 객체일 수 있어요. 자세한 내용은 perlfunc의 "require"를 보세요.
%INC — 해시 %INC는 do, require, use 연산자로 포함된 각 파일 이름에 대한 항목을 담아요. 키는 당신이 지정한 파일 이름(모듈 이름은 경로명으로 변환됨)이고, 값은 찾은 파일의 위치예요. require 연산자는 이 해시로 특정 파일이 이미 포함됐는지 판단해요.
파일이 훅(예: 서브루틴 참조, 이 훅들의 설명은 perlfunc의 "require" 참조)을 통해 로드되었다면, 이 훅은 기본적으로 파일 이름 대신 %INC에 삽입돼요. 단, 훅이 더 구체적인 정보를 제공하기 위해 %INC 항목을 스스로 설정했을 수도 있다는 점을 유의하세요.
$INC — 5.37.7부터 @INC 훅이 실행될 때, 그 훅을 담고 있는 @INC 배열의 인덱스는 $INC 변수로 지역화돼요. 훅이 반환할 때 그 값의 정수 후속자가 다음에 확인할 @INC의 인덱스를 결정하는 데 쓰여요. 그래서 -1(또는 undef)로 설정하면 @INC 배열에 대한 순회가 처음부터 재시작돼요.
보통 @INC 배열을 통한 순회는 처음부터 끝까지(0 .. $#INC)이며, 훅이 @INC 배열을 수정하면 반복자는 새로 추가된 항목이 건너뛰는 상태로 남을 수 있어요. 이 값을 바꾸면 @INC 훅이 @INC 배열을 다시 쓰고 이후에 어디서 계속할지 Perl에 알릴 수 있어요. @INC 훅에 대한 자세한 내용은 perlfunc의 "require"를 보세요.
$^I — inplace-edit 확장자의 현재 값이에요. inplace 편집을 비활성화하려면 undef를 쓰세요.
니모닉: -i 스위치의 값.
@ISA — 각 패키지는 @ISA라는 특별한 배열을 담고 있는데, 그 클래스의 부모 클래스들(있으면)의 목록을 담아요. 이 배열은 그저 스칼라들의 리스트로, 각각 패키지 이름에 대응하는 문자열이에요. 이 배열은 Perl이 메서드 해석을 할 때 검사되며, perlobj에서 다뤄요.
패키지를 로드하면서 @ISA에 추가하려면 parent 프래그마를 보세요. 권장되지 않는 base 프래그마도 이걸 하지만, 권장되지 않는 fields 프래그마와의 호환이 필요할 때를 제외하면 쓰지 말아야 해요.
$^M — 기본적으로 메모리 부족은 잡을 수 없는 치명적 오류예요. 하지만 적절히 빌드되면, Perl은 die()한 후 $^M의 내용을 비상 메모리 풀로 쓸 수 있어요. 당신의 Perl이 -DPERL_EMERGENCY_SBRK로 컴파일되고 Perl의 malloc을 쓴다고 가정해 보세요. 그러면
$^M = 'a' x (1 << 16);
은 비상용 64K 버퍼를 할당해요. perl을 컴파일할 때 커스텀 C 컴파일 플래그를 추가하는 방법에 대한 정보는 Perl 배포판의 INSTALL 파일을 보세요. 이 고급 기능의 무분별한 사용을 막기 위해 이 변수에는 English 긴 이름이 없어요.
이 변수는 Perl 5.004에 추가됐어요.
${^MAX_NESTED_EVAL_BEGIN_BLOCKS} — 이 변수는 허용되는 최대 eval EXPR/BEGIN 또는 require/BEGIN 블록 중첩 수를 결정해요. 즉 use 문의 최대 중첩도 제어한다는 뜻이에요.
기본값 1000은 정상 작업 목적에 충분히 커야 하며, 올려야 한다면 선택에 보수적이어야 해요. 그렇지 않으면 C 스택 고갈로 segfault를 만날 수 있어요. 실제 코드가 1000 이상의 사용 깊이를 가질 것 같지는 않지만, 혹시 몰라서 이걸 설정 가능하게 남겨 뒀어요.
0으로 설정하면 eval EXPR이나 require EXPR 안의 BEGIN 블록은 완전히 금지되고, 컴파일을 종료시키는 예외가 발생해요. require의 경우 예외를 던지고, eval의 경우 평소처럼 $@에 오류를 반환해요.
이 코드를 고려해 보세요.
perl -le 'sub f { eval "BEGIN { f() }"; } f()'
f()를 호출할 때마다 상당한 C 스택을 소비하고, 이 변수는 C 스택을 고갈시켜 segfault를 일으키는 대신 이런 코드가 죽게 하는 데 쓰여요. 말할 필요도 없이 이런 코드는 흔치 않아서, 실제로 설정을 올릴 필요는 없을 거예요. 하지만 제한된 시간 동안 0으로 설정하면 eval EXPR 중에 BEGIN{} 블록이 실행되는 것을 막는 데 유용할 수 있어요.
이걸 1로 설정하면 이런 코드에는 영향을 주지 않는다는 점을 유의하세요.
BEGIN { $n += 1; BEGIN { $n += 2; BEGIN { $n += 4 } } }
이유는 BEGIN 블록은 완성되면 즉시 실행되어, 가장 안쪽 것이 그것을 포함한 것들이 컴파일을 끝내기도 전에 실행되고, 깊이가 1을 넘지 않기 때문이에요. 사실 위 코드는 이것과 동등해요.
BEGIN { $n += 4; }
BEGIN { $n += 2; }
BEGIN { $n += 1; }
그래서 ${^MAX_NESTED_EVAL_BEGIN_BLOCKS}가 1이면 이 코드를 막지 못하는 이유가 명백해져요.
오직 eval이나 require(어쩌면 use를 통해) 안에서 실행된 BEGIN만 영향을 받아요.
$^O — 이 Perl 사본이 빌드된 운영 체제의 이름으로, 구성 과정에서 결정돼요. 예시는 perlport의 "PLATFORMS"를 보세요.
값은 $Config{'osname'}과 동일해요. Config와 perlrun에 문서화된 -V 명령줄 스위치도 보세요.
Windows 플랫폼에서 $^O는 그리 도움이 되지 않아요. 항상 MSWin32라서 95/98/ME/NT/2000/XP/CE/.NET 사이를 구분하지 못하니까요. 변형들을 구분하려면 Win32::GetOSName()이나 Win32::GetOSVersion()(Win32와 perlport 참조)을 쓰세요.
이 변수는 Perl 5.003에 추가됐어요.
%SIG — 해시 %SIG는 시그널에 대한 시그널 핸들러를 담아요. 예를 들어:
sub handler { # 1st argument is signal name
my ($sig) = @_;
print "Caught a SIG$sig--shutting down\n";
close($LOG);
exit(0);
}
$SIG{'INT'} = \&handler;
$SIG{'QUIT'} = \&handler;
...
$SIG{'INT'} = 'DEFAULT'; # restore default action
$SIG{'QUIT'} = 'IGNORE'; # ignore SIGQUIT
'IGNORE' 값을 쓰는 것은 보통 시그널을 무시하는 효과를 내지만, CHLD 시그널은 예외예요. 이 특별한 경우에 대한 자세한 내용은 perlipc을 보세요. 빈 문자열이나 undef를 값으로 쓰는 것은 'DEFAULT'와 같은 효과를 내요.
다른 예시들이 여기 있어요.
$SIG{"PIPE"} = "Plumber"; # assumes main::Plumber (not
# recommended)
$SIG{"PIPE"} = \&Plumber; # just fine; assume current
# Plumber
$SIG{"PIPE"} = *Plumber; # somewhat esoteric
$SIG{"PIPE"} = Plumber(); # oops, what did Plumber()
# return??
시그널 핸들러 이름으로 bareword를 쓰지 않도록 주의하세요. 실수로 호출해 버릴 수 있으니까요.
어떤 기존 함수에도 대응하지 않는 문자열이나 코드 슬롯을 담지 않는 glob을 쓰는 것은 'IGNORE'와 동등하지만, 핸들러가 호출될 때 경고가 발생해요(아래에서 설명하는 내부 훅에 대해서는 경고가 발생하지 않아요).
시스템에 sigaction() 함수가 있으면 시그널 핸들러가 그것으로 설치돼요. 즉 신뢰할 수 있는 시그널 처리를 얻는다는 뜻이에요.
시그널의 기본 전달 정책은 Perl v5.8.0에서 즉시(일명 "unsafe")에서 지연(일명 "safe signals")으로 바뀌었어요. 자세한 내용은 perlipc을 보세요.
%SIG 해시로 특정 내부 훅을 설정할 수도 있어요. $SIG{__WARN__}이 나타내는 루틴은 경고 메시지가 출력되려 할 때 호출돼요. 경고 메시지는 첫 번째 인자로 전달돼요. __WARN__ 훅이 있으면 경고를 STDERR로 평범하게 출력하는 것을 억제해요. 이것으로 경고를 변수에 저장하거나, 이렇게 경고를 치명적 오류로 바꿀 수 있어요.
local $SIG{__WARN__} = sub { die $_[0] };
eval $proggie;
__WARN__은 'IGNORE' 훅을 지원하지 않으므로, 그 효과는 'DEFAULT'를 쓰는 것과 같아요. 빈 서브루틴으로 경고를 비활성화할 수 있어요.
local $SIG{__WARN__} = sub {};
$SIG{__DIE__}가 나타내는 루틴은 치명적 예외가 던져지려 할 때 호출돼요. 오류 메시지는 첫 번째 인자로 전달돼요. __DIE__ 훅 루틴이 반환하면, 예외 처리는 훅이 없었을 때처럼 계속돼요. 단, 훅 루틴 자체가 예외를 던지지 않으면요. __DIE__ 핸들러는 호출 중에 명시적으로 비활성화되어, __DIE__ 핸들러에서 죽을 수 있게 해 줘요. __WARN__도 마찬가지예요.
$SIG{__DIE__} 훅은 eval() 안에서도 호출돼요. 그렇게 되도록 의도된 적은 없었지만, 구현 결함이 이걸 가능하게 만들었어요. 이것은 $@에서 보류 중인 예외를 다시 쓰는 것 같은 이상한 원격 작동을 허용했기 때문에 한때 deprecated였어요. 사용자들이 보류 중인 예외 다시 쓰기가 실제로 유용한 기능이지 버그가 아니라는 것을 발견했으므로, 이를 바로잡으려는 계획은 폐기됐어요.
$SIG{__DIE__} 훅은 'IGNORE'를 지원하지 않아요. 'DEFAULT'와 같은 효과를 가져요.
__DIE__/__WARN__ 핸들러는 한 가지 점에서 아주 특별해요: 파서가 (아마도) 찾은 오류를 보고하도록 호출될 수 있어요. 그런 경우 파서가 일관되지 않은 상태일 수 있으므로, 그런 핸들러에서 Perl 코드를 평가하려는 어떤 시도든 아마 segfault를 일으킬 거예요. 이는 Perl 파싱에서 비롯된 경고나 오류는 이렇게 극도의 주의로 사용해야 한다는 뜻이에요.
require Carp if defined $^S;
Carp::confess("Something wrong") if defined &Carp::confess;
die "Something wrong, but could not load Carp to give "
. "backtrace...\n\t"
. "To see backtrace try starting Perl with -MCarp switch";
여기서 첫 번째 줄은 핸들러를 호출한 게 파서가 아닌 한에서만 Carp를 로드해요. 두 번째 줄은 Carp를 쓸 수 있으면 역추적을 출력하고 죽어요. 세 번째 줄은 Carp를 쓸 수 없을 때만 실행돼요.
예외 핸들러에서 $^S 변수에 대해 생각해야 한다는 것 자체가 그저 잘못된 것이에요. 현재 구현된 $SIG{__DIE__}는 심각하고 추적하기 어려운 오류를 불러오죠. 피하고, 대신 END{}나 CORE::GLOBAL::die 재정의를 사용하세요.
추가 정보는 perlfunc의 "die", "warn", "eval"과 warnings을 보세요.
%{^HOOK} — 이 해시는 감싸기 어렵거나 불가능한 다양한 perl 키워드가 호출될 때 호출되는 coderef를 담아요. 이 해시의 키는 훅이 걸린 키워드 이름 뒤에 밑줄 두 개와 단계 용어("before" 또는 "after")가 붙은 것으로 이름 지어져요.
문서화된 키가 아닌 것을 수정하려 하거나, 해시에 코드 참조나 undef 이외의 것을 저장하려 하면 Perl은 오류를 던져요. 객체로 훅을 구현하고 싶다면 커링을 사용해 객체를 익명 코드 참조에 내장할 수 있어요.
현재 훅을 걸 수 있는 키워드는 require 하나뿐이지만, 향후 릴리스에서 훅 지원이 있는 추가 키워드가 있을 것으로 기대돼요.
require__before — ${^HOOK}{require__before}가 나타내는 루틴은 require가 %INC를 확인하고, @INC를 조회하고, INC 훅을 호출하거나, 어떤 코드를 컴파일하기 전에 호출돼요. 단일 인자, 즉 require되는 항목의 파일 이름(패키지 이름은 경로로 변환됨)으로 호출돼요. 어떤 파일을 로드할지 바꾸기 위해 이 파일 이름을 수정할 수 있어요. 훅이 실행 중에 죽으면 require가 실행되는 것을 막아요.
require 키워드가 실행되기 전과 후에 공유 상태로 작업을 수행하기 쉽게 하기 위해, require__before 훅은 require가 완료될 때 차례로 실행될 "post-action" coderef를 반환할 수 있어요. 이 coderef는 require가 성공적으로 완료됐든 예외를 던졌든 관계없이 실행돼요. require된 파일 이름으로 호출돼요. %INC를 확인해 require가 성공했는지 판단할 수 있어요. require__before 훅의 다른 반환 값은 조용히 무시돼요.
require__before 훅은 FIFO 순서로 호출되고, 훅이 코드 참조를 반환하면 그 코드 참조들은 FILO 순서로 호출돼요. 다시 말해 A가 B를 require하고 B가 C를 require하면, require__before는 먼저 A에, 그다음 B에, 그다음 C에 호출되고, post-action 코드 참조는 먼저 C에, 그다음 B에, 마지막으로 A에 실행돼요.
잘 작동하는 코드는 require__before 훅을 설정할 때 이전에 설치된 훅이 호출되고, 그 반환 값이 코드 참조라면 그것도 호출되도록 보장해야 해요. 예제 구현은 perlfunc의 "require"를 보세요.
require__after — ${^HOOK}{require__after}가 나타내는 루틴은 require가 완료된 후에 호출돼요. 단일 인자, 즉 require되는 항목의 파일 이름(패키지 이름은 경로로 변환됨)으로 호출돼요. require가 완료될 때, 예외를 통해서든 require 문의 완료를 통해서든 실행되고, %INC를 확인해 require가 성공했는지 판단할 수 있어요.
require__after 훅은 각 require된 파일에 대해 FILO 순서로 호출돼요. 다시 말해 A가 B를 require하고 B가 C를 require하면, require__after는 먼저 C에, 그다음 B에, 그다음 A에 호출돼요.
$^T — 프로그램이 실행을 시작한 시간으로, epoch(1970년 시작) 이후 초 단위예요. -M, -A, -C 파일 테스트가 반환하는 값은 이 값을 기반으로 해요.
$^V — Perl 인터프리터의 개정, 버전, 하위버전을 version 객체로 나타낸 것이에요.
이 변수는 perl v5.6.0에서 처음 나타났어요. 그 이전 perl 버전은 정의되지 않은 값을 볼 거예요. perl v5.10.0 이전의 $^V는 version 객체가 아니라 v-문자열로 표현됐어요.
$^V는 스크립트를 실행하는 Perl 인터프리터가 올바른 버전 범위에 있는지 판단하는 데 쓸 수 있어요. 예를 들어:
warn "Hashes not randomized!\n" if !$^V or $^V lt v5.8.1
version 객체는 문자열화를 오버로드하지만, $^V를 이식 가능하게 문자열 표현으로 변환하려면 sprintf()의 "%vd" 변환을 쓰세요. 이것은 v-문자열과 version 객체 둘 다에서 동작해요.
printf "version is v%vd\n", $^V; # Perl's version
실행 중인 Perl 인터프리터가 너무 오래됐을 때 실패하는 편리한 방법으로 use VERSION과 require VERSION 문서를 보세요.
Perl 버전의 십진 표현으로 "$]"도 보세요.
$^V가 $]보다 가진 주요 장점은, Perl v5.10.0 이상에서 연산자를 오버로드해서 다른 버전 표현(예: 십진, 리터럴 v-문자열, "v1.2.3", 객체)과 쉽게 비교할 수 있다는 거예요. 단점은 v5.10.0 이전에는 단지 리터럴 v-문자열이어서 쉽게 출력하거나 비교할 수 없었던 반면, $]의 동작은 모든 Perl 버전에서 변하지 않는다는 거예요.
니모닉: version 객체는 ^V를 쓴다.
$^X — 현재 Perl 사본을 실행하는 데 쓰인 이름으로, C의 argv[0]이나(지원되면) _/proc/self/exe_에서 와요.
호스트 운영 체제에 따라 $^X의 값은 perl 프로그램 파일의 상대 또는 절대 경로명일 수도, perl을 호출하는 데 쓰인 문자열이지만 perl 프로그램 파일의 경로명은 아닐 수도 있어요. 또한 대부분의 운영 체제는 PATH 환경 변수에 없는 프로그램을 호출하는 것을 허용하므로, $^X의 값이 PATH에 있다는 보장은 없어요. VMS의 경우 값에 버전 번호가 포함될 수도 있고 아닐 수도 있어요.
보통 $^X의 값으로 현재 실행 중인 것과 같은 perl의 독립 사본을 다시 호출할 수 있어요. 예를 들면:
@first_run = `$^X -le "print int rand 100 for 1..100"`;
하지만 모든 운영 체제가 명령 출력의 포킹이나 캡처를 지원하는 것은 아니므로, 이 복잡한 문장은 이식 가능하지 않을 수 있다는 점을 기억하세요.
$^X의 값을 파일의 경로 이름으로 쓰는 것은 안전하지 않아요. 실행 파일에 필수 접미사가 있는 일부 운영 체제에서는 명령을 호출할 때 접미사 사용을 요구하지 않기 때문이에요. $^X의 값을 경로 이름으로 변환하려면 다음 문장들을 쓰세요.
# Build up a set of file names (not command names).
use Config;
my $this_perl = $^X;
if ($^O ne 'VMS') {
$this_perl .= $Config{_exe}
unless $this_perl =~ m/$Config{_exe}$/i;
}
많은 운영 체제가 Perl 프로그램 파일에 대한 읽기 접근이 있는 누구든 그것을 복사하고, 복사본을 패치한 후 실행할 수 있도록 허용하므로, 보안에 민감한 Perl 프로그래머는 $^X가 참조하는 복사본이 아니라 설치된 perl 사본을 호출하도록 주의해야 해요. 다음 문장들이 이 목표를 이루고, 명령으로 호출하거나 파일로 참조할 수 있는 경로명을 만들어 내요.
use Config;
my $secure_perl_path = $Config{perlpath};
if ($^O ne 'VMS') {
$secure_perl_path .= $Config{_exe}
unless $secure_perl_path =~ m/$Config{_exe}$/i;
}
정규식 관련 변수 (Variables related to regular expressions)
정규식 관련 특수 변수 대부분은 부수 효과(side effect)예요. Perl은 매치가 성공적으로 완료되면 이 변수들을 설정하므로, 사용하기 전에 매치 결과를 확인해야 해요. 예를 들어:
if ( /P(A)TT(ER)N/ ) {
print "I found $1 and $2\n";
}
이 변수들은 읽기 전용이며, 명시적으로 다르게 동작한다고 문서화된 몇 가지 예외를 빼면 동적 스코프 변수처럼 동작해요. 자세한 내용은 다음 절을 보세요.
정규식 변수의 스코프 규칙 (Scoping Rules of Regex Variables)
정규식 변수는 프로그래머가 현재 동적 스코프에서 가장 최근의 성공적인 정규식 매치의 상태에 접근할 수 있게 해 줘요.
변수 자체는 전역이고 스코프가 없지만, 그들이 접근하는 데이터는 동적 스코프 변수처럼 스코프가 지정돼요. 모든 성공적인 매치가 전역 상태 객체를 현재 블록이나 파일 스코프로 지역화하는 것처럼 동작하기 때문이에요. (동적 스코프와 local 키워드에 대한 자세한 내용은 perlsyn의 "Compound Statements"를 보세요.)
성공적인 매치 는 검색·치환 연산자 s///가 수행한 성공적인 매치와 m// 연산자가 수행한 것들을 모두 포함해요.
이 코드를 고려해 보세요.
my @state;
sub matchit {
push @state, $1; # pushes "baz"
my $str = shift;
$str =~ /(zat)/; # matches "zat"
push @state, $1; # pushes "zat"
}
{
$str = "foo bar baz blorp zat";
$str =~ /(foo)/; # matches "foo"
push @state, $1; # pushes "foo"
{
$str =~ /(pizza)/; # does NOT match
push @state, $1; # pushes "foo"
$str =~ /(bar)/; # matches "bar"
push @state, $1; # pushes "bar"
$str =~ /(baz)/; # matches "baz"
matchit($str); # see above
push @state, $1; # pushes "baz"
}
$str =~ s/noodles/rice/; # does NOT match
push @state, $1; # pushes "foo"
$str =~ s/(blorp)/zwoop/; # matches "blorp"
push @state, $1; # pushes "blorp"
}
# the following prints "foo, foo, bar, baz, zat, baz, foo, blorp"
print join ",", @state;
정확히 같은 스코프에서의 각 성공적인 매치가 이전 성공적인 매치의 매치 문맥을 덮어쓰지만, 실패한 매치는 그렇지 않다는 점을 주목하세요. 또한 안쪽 중첩 스코프에서는 바깥 동적 스코프의 이전 상태가 다른 성공적인 매치로 덮일 때까지 지속되지만, 안쪽 중첩 스코프가 종료될 때 안쪽 성공적인 매치 전에 있던 매치 문맥이 스코프가 끝나면 복원된다는 점도 주목하세요.
goto LABEL이 동적 스코프 매치 문맥과 나쁘게 상호작용할 수 있다는 알려진 문제가 있어요. 이것은 고칠 수 없을 수도 있으며, goto LABEL을 피해야 하는 여러 좋은 이유 중 하나로 간주돼요.
성능 문제 (Performance issues)
전통적으로 Perl에서 ``$```, $&, $' 세 변수 중 어느 것(또는 그 use English 동등물)이든 코드 어디에서든 사용하면, 코드가 나중에 그 변수 중 하나에 접근할지도 모르므로 이후의 모든 성공적인 패턴 매치가 매치된 문자열의 사본을 만들게 했어요. 이것은 프로그램 전체에 상당한 성능 부담을 가했으므로, 일반적으로 이 변수들의 사용은 권장되지 않았어요.
Perl 5.6.0에서 @-와 @+ 동적 배열이 도입되어 성공적인 매치의 인덱스를 제공했어요. 그래서 예를 들어 이렇게 할 수 있었죠.
$str =~ /pattern/ or die "No match";
print $`, $&, $'; # bad: performance hit
print # good: no performance hit
substr($str, 0, $-[0]),
substr($str, $-[0], $+[0] - $-[0]),
substr($str, $+[0]);
Perl 5.10.0에서 /p 매치 연산자 플래그와 ${^PREMATCH}, ${^MATCH}, ${^POSTMATCH} 변수가 도입되어, /p로 표시된 패턴에 대해서만 부담을 겪을 수 있게 했어요.
Perl 5.18.0부터 perl은 세 변수 각각의 존재를 별도로 기록하고, 필요한 문자열의 일부만 복사하기 시작했어요. 그래서
$`; $&; "abcdefgh" =~ /d/
에서 perl은 문자열의 "abcd" 부분만 복사할 거예요. 그것은 이런 것에서 큰 차이를 만들 수 있어요.
$str = 'x' x 1_000_000;
$&; # whoops
$str =~ /x/g # one char copied a million times, not a million chars
Perl 5.20.0에서 새 copy-on-write 시스템이 기본으로 활성화되어, 마침내 이 세 변수의 성능 문제 대부분을 고치고 어디서든 안전하게 쓸 수 있게 만들었어요.
Devel::NYTProf와 Devel::FindAmpersand 모듈은 코드에서 이 문제가 있는 매치 변수들을 찾는 데 도움을 줄 수 있어요.
$1, $2, ... ($
빈 문자열과 매치하는 캡처 버퍼와 선택적인 캡처 버퍼 사이에는 차이가 있다는 점을 유의하세요. 예를 들어 (x?)와 (x)?. 후자는 undef일 수 있지만 전자는 아닙니다.
이 변수들은 읽기 전용이에요.
니모닉: \\digits와 같다.
@{^CAPTURE} — 마지막 성공적인 패턴 매치의 캡처 버퍼들(있으면)의 내용을 노출하는 배열이에요. 이미 벗어난 중첩 블록에서 매치된 패턴은 세지 않아요.
@{^CAPTURE}의 0 인덱스가 $1과 동등하고, 1 인덱스가 $2와 동등하다는 점을 유의하세요.
if ("foal" =~ /(.)(.)(.)(.)/) {
print join "-", @{^CAPTURE};
}
는 "f-o-a-l"을 출력해야 해요.
$<digits> ($1, $2, ...), "%{^CAPTURE}", "%{^CAPTURE_ALL}"도 보세요.
다른 정규식 마법 변수들과 달리 @{^CAPTURE}에 해당하는 단일 문자 동등물이 없다는 점을 유의하세요. 또한 이 배열의 첨자를 보간할 때 반드시 구분 변수 형태를 써야 한다는 점을 주의하세요. 예를 들어
print "${^CAPTURE[0]}";
이 형태와 그 용도에 대한 자세한 내용은 perldata의 "중괄호를 쓴 구분 변수 이름"을 보세요.
이 변수는 5.25.7에 추가됐어요.
더 오래된 Perl에서 이 기능에 접근해야 한다면 정규식 직후에 이 함수를 쓸 수 있어요.
sub get_captures {
my $last_idx = $#-;
my @arr = 1 .. $last_idx;
my @ret = map {
no strict 'refs';
$$_;
} @arr;
return @ret;
}
$& — 마지막 성공적인 패턴 매치가 매치한 문자열이에요. ("정규식 변수의 스코프 규칙"을 보세요.)
코드에서 이 변수(한 번만이라도)를 쓰는 것의 심각한 성능 함의는 위의 "성능 문제"를 보세요.
이 변수는 읽기 전용이며, 그 값은 동적 스코프예요.
니모닉: 일부 편집기의 &와 같다.
${^MATCH} — 패턴이 /p 수정자로 컴파일되거나 실행됐을 때만 정의된 값을 반환하는 것이 보장돼요.
이것은 $&($MATCH)와 비슷하지만, 사용하려면 패턴을 실행할 때 /p 수정자를 써야 하고, 그 변수와 연관된 성능 부담을 지지 않아요.
위의 "성능 문제"를 보세요.
이 변수는 Perl v5.10.0에 추가됐어요.
읽기 전용이며, 그 값은 동적 스코프예요.
$\` — 마지막 성공적인 패턴 매치가 매치한 것의 앞에 오는 문자열이에요. ("정규식 변수의 스코프 규칙"을 보세요.)
코드에서 이 변수(한 번만이라도)를 쓰는 것의 심각한 성능 함의는 위의 "성능 문제"를 보세요.
이 변수는 읽기 전용이며, 그 값은 동적 스코프예요.
니모닉: ````` 는 종종 인용 문자열보다 앞선다.
${^PREMATCH} — 패턴이 /p 수정자로 실행됐을 때만 정의된 값을 반환하는 것이 보장돼요.
이것은 ``$```($PREMATCH)와 비슷하지만, 사용하려면 패턴을 실행할 때 /p 수정자를 써야 하고, 그 변수와 연관된 성능 부담을 지지 않아요.
위의 "성능 문제"를 보세요.
이 변수는 Perl v5.10.0에 추가됐어요.
읽기 전용이며, 그 값은 동적 스코프예요.
$' — 마지막 성공적인 패턴 매치가 매치한 것의 뒤에 오는 문자열이에요. ("정규식 변수의 스코프 규칙"을 보세요.) 예:
local $_ = 'abcdefghi';
/def/;
print "$`:$&:$'\n"; # prints abc:def:ghi
코드에서 이 변수(한 번만이라도)를 쓰는 것의 심각한 성능 함의는 위의 "성능 문제"를 보세요.
이 변수는 읽기 전용이며, 그 값은 동적 스코프예요.
니모닉: ' 는 종종 인용 문자열 뒤에 온다.
${^POSTMATCH} — 패턴이 /p 수정자로 컴파일되거나 실행됐을 때만 정의된 값을 반환하는 것이 보장돼요.
이것은 $'($POSTMATCH)와 비슷하지만, 사용하려면 패턴을 실행할 때 /p 수정자를 써야 하고, 그 변수와 연관된 성능 부담을 지지 않아요.
위의 "성능 문제"를 보세요.
이 변수는 Perl v5.10.0에 추가됐어요.
읽기 전용이며, 그 값은 동적 스코프예요.
$+ — 마지막 성공적인 검색 패턴의 가장 높게 사용된 캡처 그룹이 매치한 텍스트예요. ("정규식 변수의 스코프 규칙"을 보세요.) 논리적으로 정의된 값이 있는 가장 높은 번호의 캡처 변수($1, $2, ...)와 동등해요.
대안 패턴 집합 중 어느 것이 매치됐는지 모를 때 유용해요. 예를 들어:
if (/Version: (.*)|Revision: (.*)|Release: (.*)/) {
$rev = $+;
# like $rev = $3 // $2 // $1;
}
이 변수는 읽기 전용이며, 그 값은 동적 스코프예요.
니모닉: 긍정적이고 전향적으로 생각하라.
$^N — 마지막 성공적인 매치에서 가장 최근에 닫힌(즉 가장 오른쪽 닫는 괄호를 가진) 사용된 그룹이 매치한 텍스트예요. ("정규식 변수의 스코프 규칙"을 보세요.)
이것은 $+와 미묘하게 달라요. 예를 들어
"ab" =~ /^((.)(.))$/
에서 우리는
$1,$^N have the value "ab"
$2 has the value "a"
$3,$+ have the value "b"
을 가져요.
이것은 주로 (?{...}) 블록 안에서 최근에 매치된 텍스트를 조사하는 데 쓰여요. 예를 들어 텍스트를 변수에 효과적으로 캡처하려면($1, $2 등에 더해서), (...)를 이것으로 바꾸세요.
(?:(...)(?{ $var = $^N }))
이렇게 $var를 설정하고 사용하면 정확히 어느 번호의 괄호 집합인지 걱정하지 않아도 돼요.
이 변수는 읽기 전용이며, 그 값은 동적 스코프예요.
이 변수는 Perl v5.8.0에 추가됐어요.
니모닉: 가장 최근에 닫힌 (아마도) 중첩 괄호.
@+ — 이 배열은 마지막 성공적인 매치와 패턴이 담고 있는 일치하는 캡처 버퍼들의 끝의 오프셋을 담아요. ("정규식 변수의 스코프 규칙"을 보세요.)
담는 요소 수는 어떤 캡처 버퍼가 실제로 매치했는지와 무관하게 패턴의 캡처 버퍼 수보다 하나 많아요. 이것으로 패턴에 캡처 버퍼가 몇 개인지 알 수 있어요. (@-와 달리요. @-는 요소가 더 적을 수 있어요.)
$+[0]은 전체 매치의 끝의 문자열 오프셋이에요. 이것은 매치된 변수에 pos 함수를 호출했을 때 반환되는 값과 같아요. 이 배열의 n 번째 요소는 n 번째 하위 매치의 끝 오프셋을 담아요. 그래서 $+[1]은 $1이 끝나는 지점을 지난 오프셋이고, $+[2]는 $2가 끝나는 지점을 지난 오프셋이에요. $#+로 마지막 성공적인 매치에 하위 그룹이 몇 개였는지 알 수 있어요. @- 변수에 제시된 예시를 보세요.
이 변수는 읽기 전용이며, 그 값은 동적 스코프예요.
이 변수는 Perl v5.6.0에 추가됐어요.
%+ / %{^CAPTURE} — @+와 비슷하게, %+ 해시는 현재 활성 동적 스코프에서 마지막 성공적인 매치의, 존재한다면 명명된 캡처 버퍼에 대한 접근을 허용해요. ("정규식 변수의 스코프 규칙"을 보세요.)
예를 들어 $+{foo}는 다음 매치 후에 $1과 동등해요.
'foo' =~ /(?<foo>foo)/;
%+ 해시의 키는 캡처한(그래서 정의된 값과 연관된) 버퍼의 이름만 나열해요.
여러 개의 서로 다른 캡처 그룹이 같은 이름을 가지면, $+{NAME}은 매치에서 가장 왼쪽의 정의된 그룹을 가리킬 거예요.
%+의 밑바탕 동작은 Tie::Hash::NamedCapture 모듈이 제공해요.
참고: %-와 %+는 마지막 성공적인 정규식과 연관된 공통 내부 해시에 대한 tied 뷰예요. 그래서 each로 그것들에 대한 반복 접근을 섞으면 예측할 수 없는 결과가 나올 수 있어요. 마찬가지로 마지막 성공적인 매치가 바뀌면 결과가 놀라울 수 있어요.
이 변수는 Perl v5.10.0에 추가됐어요. %{^CAPTURE} 별칭은 5.25.7에 추가됐어요.
읽기 전용이며, 그 값은 동적 스코프예요.
@- — 이 배열은 마지막 성공적인 매치와 그것이 담고 있는 캡처 버퍼들의 시작의 오프셋을 담아요. ("정규식 변수의 스코프 규칙"을 보세요.)
담는 요소 수는 실제로 무언가를 매치한 가장 높은 캡처 버퍼(하위 그룹이라고도 함)의 수보다 하나 많아요. (@+와 달리요. @+는 요소가 더 많을 수 있어요.)
$-[0]은 마지막 성공적인 매치의 시작 오프셋이에요. $-[n]은 n-번째 하위 패턴이 매치한 부분 문자열의 시작 오프셋이거나, 하위 패턴이 매치하지 않았으면 undef예요.
그래서 $_에 대한 매치 후, $&는 substr $_, $-[0], $+[0] - $-[0]와 일치해요. 비슷하게 $n은 $-[n]이 정의되어 있으면 substr $_, $-[n], $+[n] - $-[n]와 일치하고, $+는 substr $_, $-[$#-], $+[$#-] - $-[$#-]와 일치해요. $#-로 마지막 성공적인 매치에서 마지막으로 매치된 하위 그룹을 찾을 수 있어요. 정규식의 하위 그룹 수인 $#+와 대조하세요.
$-[0]은 전체 매치의 시작의 문자열 오프셋이에요. 이 배열의 n 번째 요소는 n 번째 하위 매치의 오프셋을 담아요. 그래서 $-[1]은 $1이 시작하는 오프셋이고, $-[2]는 $2가 시작하는 오프셋이에요.
어떤 변수 $var에 대한 매치 후:
``$```는 substr($var, 0, $-[0])와 같다 — $&는 substr($var, $-[0], $+[0] - $-[0])와 같다 — $'는 substr($var, $+[0])와 같다 — $1은 substr($var, $-[1], $+[1] - $-[1])와 같다 — $2는 substr($var, $-[2], $+[2] - $-[2])와 같다 — $3은 substr($var, $-[3], $+[3] - $-[3])와 같다.
이 변수는 읽기 전용이며, 그 값은 동적 스코프예요.
이 변수는 Perl v5.6.0에 추가됐어요.
%- / %{^CAPTURE_ALL} — %+와 비슷하게, 이 변수는 현재 활성 동적 스코프에서 마지막 성공적인 매치의 명명된 캡처 그룹에 대한 접근을 허용해요. ("정규식 변수의 스코프 규칙"을 보세요.) 정규식에서 발견된 각 캡처 그룹 이름에 대해, 그 이름을 가진 모든 버퍼가 캡처한 값들의 목록을 담은 배열에 대한 참조를 연관시켜요(여러 개일 수 있다면), 나타나는 순서대로요.
예시를 볼게요.
if ('1234' =~ /(?<A>1)(?<B>2)(?<A>3)(?<B>4)/) {
foreach my $bufname (sort keys %-) {
my $ary = $-{$bufname};
foreach my $idx (0 .. $#$ary) {
print "\$-{$bufname}[$idx] : ",
(defined($ary->[$idx])
? "'$ary->[$idx]'"
: "undef"),
"\n";
}
}
}
는 이렇게 출력해요.
$-{A}[0] : '1'
$-{A}[1] : '3'
$-{B}[0] : '2'
$-{B}[1] : '4'
%- 해시의 키는 정규식에서 발견된 모든 버퍼 이름에 대응해요.
%-의 동작은 Tie::Hash::NamedCapture 모듈을 통해 구현돼요.
참고: %-와 %+는 마지막 성공적인 정규식과 연관된 공통 내부 해시에 대한 tied 뷰예요. 그래서 each로 그것들에 대한 반복 접근을 섞으면 예측할 수 없는 결과가 나올 수 있어요. 마찬가지로 마지막 성공적인 매치가 바뀌면 결과가 놀라울 수 있어요. "정규식 변수의 스코프 규칙"을 보세요.
이 변수는 Perl v5.10.0에 추가됐어요. %{^CAPTURE_ALL} 별칭은 5.25.7에 추가됐어요.
읽기 전용이며, 그 값은 동적 스코프예요.
${^LAST_SUCCESSFUL_PATTERN} — 현재 스코프에서 매치한 마지막 성공적인 패턴이에요. 빈 패턴은 기본적으로 이것에 매치돼요. 예를 들어:
if (m/foo/ || m/bar/) {
s//BLAH/;
}
와
if (m/foo/ || m/bar/) {
s/${^LAST_SUCCESSFUL_PATTERN}/BLAH/;
}
은 동등해요.
이것으로 어떤 패턴이 마지막으로 매치됐는지 디버깅하거나, 그것으로 다시 매치할 수 있어요.
Perl 5.37.10에 추가됐어요.
$^R — 마지막 성공적인 (?{ code }) 정규식 어서션(perlre 참조)의 평가 결과예요.
이 변수는 쓸 수 있으며, 그 값은 다른 정규식 변수들과 달리 정상적으로 스코프가 지정돼요.
이 변수는 Perl 5.005에 추가됐어요.
${^RE_COMPILE_RECURSION_LIMIT} — 정규식 컴파일 중 어느 시점에 열려 있고 닫히지 않은 괄호 그룹이 있을 수 있는 최대 수를 주는 현재 값이에요. 기본값은 현재 1000개의 중첩 그룹이에요. 필요와 사용 가능한 메모리 양에 따라 조정할 수 있어요.
이 변수는 Perl v5.30.0에 추가됐어요.
${^RE_DEBUG_FLAGS} — 정규식 디버깅 플래그의 현재 값이에요. re 'debug' 모듈이 로드됐어도 디버그 출력 없이 0으로 설정해요. 자세한 내용은 re를 보세요.
이 변수는 Perl v5.10.0에 추가됐어요.
${^RE_TRIE_MAXBUF} — 특정 정규식 최적화가 어떻게 적용되고 얼마나 많은 메모리를 쓰는지 제어해요. 이 값은 기본적으로 65536이며 512kB 임시 캐시에 해당해요. 큰 대안(alternation)을 매치할 때 메모리를 속도로 바꾸려면 더 높은 값으로 설정하세요. 최적화가 최대한 메모리 보수적으로 되되 여전히 일어나길 원하면 더 낮은 값으로, 그리고 최적화를 막고 가장 많은 메모리를 아끼려면 음수 값으로 설정하세요. 정상 상황에서 이 변수는 당신에게 관심이 없어야 해요.
이 변수는 Perl v5.10.0에 추가됐어요.
파일핸들 관련 변수 (Variables related to filehandles)
현재 선택된 파일핸들에 의존하는 변수들은 IO::Handle 객체에서 적절한 객체 메서드를 호출해 설정할 수 있어요. 다만 이것은 보통 내장 변수를 쓰는 것보다 약간 덜 효율적이에요. (아래의 요약 줄에는 HANDLE이라는 단어가 포함돼 있어요.)
Perl v5.14.0 이전 버전에서는
use IO::Handle;
을 먼저 말해야
HANDLE->method(EXPR)
을 쓸 수 있었어요.
Perl v5.14.0부터는 먼저 모듈을 로드하지 않고도 어떤 파일핸들도 객체로 쓸 수 있어요.
각 메서드는 IO::Handle 속성의 옛 값을 반환해요. 메서드들은 선택적 EXPR을 받는데, 제공되면 해당 IO::Handle 속성의 새 값을 지정해요. 제공되지 않으면 대부분의 메서드는 현재 값에 아무것도 하지 않아요—다만 달라지기 위해 당신을 위해 1을 가정하는 autoflush()는 제외해요.
이 변수들 중 일부는 "읽기 전용"으로 간주돼요. 즉 이 변수에 직접이든 참조를 통해서든 간접적으로 할당하려 하면 런타임 예외가 발생한다는 뜻이에요.
이 문서에서 설명하는 대부분의 특수 변수의 기본값을 수정할 때는 매우 주의해야 해요. 대부분의 경우 변경하기 전에 이 변수들을 지역화하고 싶을 거예요. 그렇지 않으면 변경이 당신이 바꾼 특수 변수의 기본값에 의존하는 다른 모듈에 영향을 줄 수 있으니까요. 이것이 파일 전체를 한 번에 읽는 올바른 방법 중 하나예요.
open my $fh, "<", "foo" or die $!;
local $/; # enable localized slurp mode
my $content = <$fh>;
close $fh;
하지만 다음 코드는 꽤 나빠요.
open my $fh, "<", "foo" or die $!;
undef $/; # enable slurp mode
my $content = <$fh>;
close $fh;
다른 모듈이 어떤 파일에서 기본 "라인 모드"로 데이터를 읽으려 할 수 있으므로, 방금 제시한 코드가 실행됐다면 $/의 전역 값은 같은 Perl 인터프리터에서 실행되는 다른 코드를 위해 이제 바뀌었기 때문이에요.
보통 변수를 지역화할 때 이 변경이 가능한 한 짧은 스코프에 영향을 주도록 하고 싶어요. 이미 짧은 {} 블록 안이 아니라면 직접 만들어야 해요. 예를 들어:
my $content = '';
open my $fh, "<", "foo" or die $!;
{
local $/;
$content = <$fh>;
}
close $fh;
여기 당신의 코드가 어떻게 망가질 수 있는지 예가 있어요.
for ( 1 .. 3 ) {
$\ = "\r\n";
nasty_break();
print "$_";
}
sub nasty_break {
$\ = "\f";
# do something with $_
}
당신은 이 코드가 다음의 동등물을 출력하길 기대하겠죠.
"1\r\n2\r\n3\r\n"
하지만 대신 이렇게 나와요.
"1\f2\f3\f"
왜? nasty_break()가 $\을 먼저 지역화하지 않고 수정하기 때문이에요. nasty_break()에서 설정한 값은 반환할 때 여전히 거기 있어요. 고치는 방법은 local()을 추가해서 값이 nasty_break() 밖으로 새지 않게 하는 거예요.
local $\ = "\f";
이런 짧은 예에서는 문제를 알아차리기 쉽지만, 더 복잡한 코드에서는 특수 변수에 대한 변경을 지역화하지 않으면 골치 아픈 일을 찾는 셈이에요.
$ARGV — <>로 읽을 때 현재 파일의 이름을 담아요.
@ARGV — 배열 @ARGV는 스크립트를 위한 명령줄 인자를 담아요. $#ARGV는 일반적으로 인자 수에서 하나를 뺀 값이에요. $ARGV[0]이 첫 번째 인자이지, 프로그램의 명령 이름 자체가 아니기 때문이에요. 명령 이름은 "$0"을 보세요.
ARGV — @ARGV의 명령줄 파일 이름들을 순회하는 특수 파일핸들이에요. 보통 다이아몬드 연산자 <>에서 null 파일핸들로 쓰여요. 현재 ARGV는 <> 연산자 안에서만 마법 효과를 가진다는 점을 유의하세요. 다른 곳에서는 <>가 연 마지막 파일에 해당하는 평범한 파일핸들일 뿐이에요. 특히 파일핸들을 기대하는 함수에 \\*ARGV를 매개변수로 넘기는 것은 함수가 @ARGV의 모든 파일 내용을 자동으로 읽게 하지 않을 수 있어요.
ARGVOUT — -i로 제자리 편집(edit-in-place)을 할 때 현재 열려 있는 출력 파일을 가리키는 특수 파일핸들이에요. 삽입을 많이 해야 하고 $_를 계속 수정하고 싶지 않을 때 유용해요. -i 스위치에 대해 perlrun을 보세요.
$, (IO::Handle->output_field_separator(EXPR)) — print 연산자의 출력 필드 구분자예요. 정의되어 있으면 이 값은 print의 각 인자 사이에 출력돼요. 기본값은 undef예요.
핸들에서 output_field_separator()를 호출할 수 없고 정적 메서드로만 호출할 수 있어요. IO::Handle을 보세요.
니모닉: print 문에 ","가 있을 때 출력되는 것.
$. (HANDLE->input_line_number(EXPR)) — 마지막으로 접근한 파일핸들의 현재 줄 번호예요.
Perl의 각 파일핸들은 그것에서 읽힌 줄 수를 센다. ($/의 값에 따라 Perl의 "줄" 개념이 당신의 것과 일치하지 않을 수 있어요.) 파일핸들에서 줄이 읽힐 때(readline()이나 <>로), 또는 그것에 tell()이나 seek()이 호출될 때, $.은 그 파일핸들의 줄 카운터의 별칭이 돼요.
$.에 할당해서 카운터를 조정할 수 있지만, 이것은 실제로 seek 포인터를 움직이지 않아요. $.을 지역화하는 것은 파일핸들의 줄 수를 지역화하지 않아요. 대신 $.이 현재 어느 파일핸들에 별칭되는지에 대한 perl의 개념을 지역화해요.
$.은 파일핸들이 닫힐 때 리셋되지만, 중간에 close() 없이 열린 파일핸들이 다시 열리면 아니에요. 자세한 내용은 perlop의 "I/O Operators"를 보세요. <>는 명시적 close를 절대 하지 않으므로, 줄 번호는 ARGV 파일들을 가로질러 증가해요(하지만 perlfunc의 "eof"의 예시를 보세요).
HANDLE->input_line_number(EXPR)로 마지막에 어떤 핸들을 접근했는지 걱정하지 않고 주어진 파일핸들의 줄 카운터에 접근할 수도 있어요.
니모닉: 많은 프로그램이 현재 줄 번호를 의미하는 데 "."을 쓴다.
$/ (IO::Handle->input_record_separator(EXPR)) — 입력 레코드 구분자로, 기본값은 새 줄이에요. 이것은 Perl의 "줄" 개념에 영향을 줘요. awk의 RS 변수처럼 동작하며, 빈 줄을 종료자로 취급하는 것(null 문자열로 설정하면 빈 줄은 공백이나 탭을 담을 수 없음)을 포함해요. 여러 문자 종료자와 매치하도록 여러 문자 문자열로 설정하거나, 파일 끝까지 읽도록 undef로 설정할 수 있어요. \"\\n\\n\"으로 설정하는 것은 \"\"로 설정하는 것과 약간 다른 뜻인데, 파일이 연속된 빈 줄을 담고 있으면 그렇죠. \"\"로 설정하면 둘 이상의 연속된 빈 줄을 단일 빈 줄로 취급해요. \"\\n\\n\"으로 설정하면 다음 입력 문자가 새 줄이어도 다음 단락에 속한다고 맹목적으로 가정해요.
local $/; # enable "slurp" mode
local $_ = <$FH>; # whole file now here
s/\n[ \t]+/ /g;
기억하세요: $/의 값은 문자열이지, 정규식이 아니에요. awk도 뭔가를 잘해야죠. :-)
$/을 빈 문자열로 설정하는 것—소위 단락 모드(paragraph mode) \-\-는 특별한 주의가 필요해요. $/이 \"\"로 설정되고 그 설정으로 전체 파일이 읽히면, 파일 시작의 하나 이상의 연속된 새 줄 시퀀스는 버려져요. 파일의 마지막 레코드를 제외하고, 둘 이상의 새 줄로 끝나는 각 문자 시퀀스는 하나의 레코드로 취급되어 정확히 두 개의 새 줄로 끝나도록 읽혀요. 파일의 마지막 레코드가 0개 또는 1개의 연속된 새 줄로 끝나면, 그 레코드는 그 수의 새 줄로 읽혀요. 마지막 레코드가 둘 이상의 연속된 새 줄로 끝나면, 앞선 모든 레코드처럼 두 개의 새 줄로 읽혀요.
파일에 이 문자열을 썼다고 가정해 보세요.
my $string = "\n\n\n";
$string .= "alpha beta\ngamma delta\n\n\n";
$string .= "epsilon zeta eta\n\n";
$string .= "theta\n";
my $file = 'simple_file.txt';
open my $OUT, '>', $file or die $!;
print $OUT $string;
close $OUT or die $!;
이제 단락 모드로 그 파일을 읽어요.
local $/ = ""; # paragraph mode
open my $IN, '<', $file or die $!;
my @records = <$IN>;
close $IN or die $!;
@records는 이 3개의 문자열로 구성돼요.
(
"alpha beta\ngamma delta\n\n",
"epsilon zeta eta\n\n",
"theta\n",
)
$/을 정수에 대한 참조, 정수를 담은 스칼라, 또는 정수로 변환 가능한 스칼라로 설정하면 줄 대신 레코드를 읽으려 시도하며, 최대 레코드 크기는 참조된 정수 개수의 문자예요. 그래서 이것은:
local $/ = \32768; # or \"32768\", or \$var_containing_32768
open my $fh, "<", $myfile or die $!;
local $_ = <$fh>;
$fh에서 32768자를 넘지 않는 레코드를 읽어요. 레코드 지향 파일에서 읽는 게 아니면(또는 OS에 레코드 지향 파일이 없으면), 아마 매 읽기마다 전체 데이터 덩어리를 얻을 거예요. 레코드가 설정한 레코드 크기보다 크면, 레코드를 조각으로 받아요. 레코드 크기를 0 이하로 설정하려는 것은 deprecated이며 $/의 값을 "undef"로 만들고, (나머지) 전체 파일을 읽게 할 거예요.
5.19.9부터 $/을 다른 형태의 참조로 설정하면 치명적 예외를 던져요. 이것은 향후 $/을 설정하는 새 방법을 지원하기 위한 준비예요.
VMS에서만 레코드 읽기가 PerlIO 레이어와 관련 버퍼링을 우회하므로, 같은 파일핸들에서 레코드와 비-레코드 읽기를 섞으면 안 돼요. 레코드 모드는 두 모드에 같은 버퍼링 레이어가 사용될 때만 라인 모드와 섞여요.
핸들에서 input_record_separator()를 호출할 수 없고 정적 메서드로만 호출할 수 있어요. IO::Handle을 보세요.
perlport의 "Newlines"도 보세요. "$."도 보세요.
니모닉: / 는 시를 인용할 때 줄 경계를 구분한다.
$\ (IO::Handle->output_record_separator(EXPR)) — print 연산자의 출력 레코드 구분자예요. 정의되어 있으면 이 값은 print의 마지막 인자 뒤에 출력돼요. 기본값은 undef예요.
핸들에서 output_record_separator()를 호출할 수 없고 정적 메서드로만 호출할 수 있어요. IO::Handle을 보세요.
니모닉: print 끝에 "\\n"을 추가하는 대신 $\\을 설정한다. 또한 $/과 똑같지만, Perl로부터 "돌려받는" 것이다.
$| (HANDLE->autoflush(EXPR)) — 0이 아닌 값으로 설정하면 현재 선택된 출력 채널에서 즉시 그리고 모든 쓰기·print 후에 플러시를 강제해요. 기본값은 0이에요(채널이 시스템에 의해 실제로 버퍼링되든 아니든; $|는 당신이 Perl에게 각 쓰기 후에 명시적으로 플러시하라고 요청했는지만 알려 줘요). STDOUT은 보통 출력이 터미널이면 라인 버퍼링되고, 그렇지 않으면 블록 버퍼링돼요. 이 변수를 설정하는 것은 주로 파이프나 소켓으로 출력할 때 유용해요. 예를 들어 rsh 아래에서 Perl 프로그램을 실행하면서 출력이 일어나는 대로 보고 싶을 때요. 이 변수는 입력 버퍼링에는 효과가 없어요. 그건 perlfunc의 "getc"를 보세요. 출력 채널을 선택하는 방법은 perlfunc의 "select"를 보세요. IO::Handle도 보세요.
니모닉: 파이프가 타오르듯 뜨겁기를 원할 때.
${^LAST_FH} — 이 읽기 전용 변수는 마지막으로 읽힌 파일핸들에 대한 참조를 담아요. <HANDLE>, readline, tell, eof, seek가 설정해요. $., tell, 인자 없는 eof가 쓰는 핸들이기도 해요. Perl이 오류나 경고 메시지에 ",
이 변수는 Perl v5.18.0에 추가됐어요.
포맷 관련 변수 (Variables related to formats)
포맷을 위한 특수 변수들은 파일핸들용의 부분집합이에요. Perl의 포맷에 대한 자세한 정보는 perlform을 보세요.
$^A — format() 줄을 위한 write() 누산기의 현재 값이에요. 포맷은 결과를 $^A에 넣는 formline() 호출을 포함해요. write()는 포맷을 호출한 후 $^A의 내용을 출력하고 비워요. 그래서 스스로 formline()을 호출하고 나서 그것을 보지 않는 한 $^A의 내용을 실제로 보지 못해요. perlform과 perlfunc의 "formline PICTURE,LIST"을 보세요.
$^L (IO::Handle->format_formfeed(EXPR)) — 포맷이 form feed로 출력하는 것. 기본값은 \\f예요.
핸들에서 format_formfeed()를 호출할 수 없고 정적 메서드로만 호출할 수 있어요. IO::Handle을 보세요.
$% (HANDLE->format_page_number(EXPR)) — 현재 선택된 출력 채널의 현재 페이지 번호예요.
니모닉: %는 nroff에서 페이지 번호다.
$- (HANDLE->format_lines_left(EXPR)) — 현재 선택된 출력 채널의 페이지에 남은 줄 수예요.
니모닉: lines\_on\_page - lines\_printed.
$: (IO::Handle->format_line_break_characters(EXPR)) — 포맷에서 ( ^로 시작하는) 연속 필드를 채우기 위해 문자열이 끊어질 수 있는 현재 문자 집합이에요. 기본값은 " \\n-"으로, 공백, 새 줄, 하이픈에서 끊어요.
핸들에서 format_line_break_characters()를 호출할 수 없고 정적 메서드로만 호출할 수 있어요. IO::Handle을 보세요.
니모닉: 시의 "콜론"은 줄의 일부다.
$= (HANDLE->format_lines_per_page(EXPR)) — 현재 선택된 출력 채널의 현재 페이지 길이(인쇄 가능한 줄)예요. 기본값은 60이에요.
니모닉: = 에는 가로 줄이 있다.
$^ (HANDLE->format_top_name(EXPR)) — 현재 선택된 출력 채널의 현재 페이지 상단(top-of-page) 포맷 이름이에요. 기본값은 파일핸들 이름에 _TOP을 덧붙인 것이에요. 예를 들어 STDOUT 파일핸들에 대한 기본 포맷 상단 이름은 STDOUT_TOP이에요.
니모닉: 페이지 상단을 가리킨다.
$~ (HANDLE->format_name(EXPR)) — 현재 선택된 출력 채널의 현재 보고서 포맷 이름이에요. 기본 포맷 이름은 파일핸들 이름과 같아요. 예를 들어 STDOUT 파일핸들에 대한 기본 포맷 이름은 그냥 STDOUT이에요.
니모닉: $^의 형제.
오류 변수 (Error Variables)
$@, $!, $^E, $? 변수들은 Perl 프로그램 실행 중에 나타날 수 있는 서로 다른 타입의 오류 조건에 대한 정보를 담아요. 변수들은 오류를 보고한 하위 시스템과 Perl 프로세스 사이의 "거리" 순서로 나열돼요. 그것들은 각각 Perl 인터프리터, C 라이브러리, 운영 체제, 또는 외부 프로그램이 감지한 오류에 대응해요.
이 변수들 사이의 차이를 설명하기 위해, 작은따옴표 문자열을 쓰는 다음 Perl 표현식을 고려해 보세요. 이 문장이 실행된 후 perl은 네 특수 오류 변수 모두를 설정했을 수 있어요.
eval q{
open my $pipe, "/cdrom/install |" or die $!;
my @res = <$pipe>;
close $pipe or die "bad pipe: $?, $!";
};
perl이 eval() 표현식을 실행할 때, 그것은 C 실행 시간 라이브러리의 open(), <PIPE>, close 호출을 번역하고 거기서 운영 체제 커널로 전달해요. 이 호출 중 하나가 실패하면 perl은 $!을 C 라이브러리의 errno로 설정해요.
$@은 eval될 문자열이 컴파일되지 않았거나(open이나 close가 나쁜 프로토타입으로 import된 경우), 또는 평가 중 실행된 Perl 코드가 die()하면 설정돼요. 이 경우 $@의 값은 컴파일 오류이거나, die의 인자($!와 $?를 보간함)예요. (물론 Fatal도 보세요.)
몇몇 운영 체제에서 $^E는 더 자세한 오류 지표를 담을 수 있어요. 이 경우엔 "CDROM tray not closed" 따위로요. 확장 오류 메시지를 지원하지 않는 시스템은 $^E를 $!와 같게 둬요.
마지막으로 $?은 외부 프로그램 _/cdrom/install_이 실패하면 0이 아닌 값으로 설정될 수 있어요. 위쪽 8비트는 프로그램이 만난 특정 오류 조건(프로그램의 exit() 값)을 반영해요. 아래쪽 8비트는 실패 모드, 예를 들어 시그널 사망과 코어 덤프 정보를 반영해요. 자세한 내용은 wait(2)를 보세요. 오류 조건이 감지될 때만 설정되는 $!과 $^E와 대조적으로, $? 변수는 각 wait 또는 파이프 close에서 설정되어 옛 값을 덮어써요. 이것은 모든 eval()에서 실패 시 항상 설정되고 성공 시 지워지는 $@에 더 가까워요.
자세한 내용은 $@, $!, $^E, $?에서 개별 설명을 보세요.
${^CHILD_ERROR_NATIVE} — 마지막 파이프 close, 역따옴표(````````) 명령, wait()나 waitpid()의 성공적인 호출, 또는 system() 연산자가 반환한 네이티브 상태예요. POSIX 유사 시스템에서 이 값은 POSIX 모듈이 제공하는 WIFEXITED, WEXITSTATUS, WIFSIGNALED, WTERMSIG, WIFSTOPPED, WSTOPSIG 함수로 디코딩할 수 있어요.
VMS에서는 이것이 실제 VMS 종료 상태를 반영해요. 즉 프래그마 use vmsish 'status'가 적용될 때 $?와 같아요.
이 변수는 Perl v5.10.0에 추가됐어요.
$^E — 현재 운영 체제에 특정한 오류 정보예요. 현재는 VMS, OS/2, Win32(그리고 MacPerl)에서만 \"$!\"와 다르며, 다른 모든 플랫폼에서는 $^E가 항상 $!와 같아요.
VMS에서 $^E는 마지막 시스템 오류의 VMS 상태 값을 제공해요. 이것은 $!이 제공하는 것보다 더 구체적인 마지막 시스템 오류 정보예요. $!이 EVMSERR로 설정될 때 특히 중요해요.
OS/2에서 $^E는 CRT를 통해든 perl에서 직접든 OS/2 API에 대한 마지막 호출의 오류 코드로 설정돼요.
Win32에서 $^E는 Win32 API 내부의 마지막 오류를 설명하는 Win32 호출 GetLastError()가 보고한 마지막 오류 정보를 항상 반환해요. 대부분의 Win32 특정 코드는 $^E를 통해 오류를 보고해요. ANSI C와 Unix 유사 호출은 errno를 설정하므로 대부분의 이식 가능한 Perl 코드는 $!을 통해 오류를 보고해요.
\"$!\" 설명에서 언급한 주의 사항들은 일반적으로 $^E에도 적용돼요.
이 변수는 Perl 5.003에 추가됐어요.
니모닉: 추가 오류 설명.
$^S — 인터프리터의 현재 상태예요.
$^S State
--------- -------------------------------------
undef Parsing module, eval, or main program
true (1) Executing an eval or try block
false (0) Otherwise
첫 번째 상태는 $SIG{__DIE__}와 $SIG{__WARN__} 핸들러에서 일어날 수 있어요.
영어 이름 $EXCEPTIONS\_BEING\_CAUGHT는 약간 오해를 부르는데, main 프로그램의 컴파일은 예외를 잡지 않으므로 undef 값이 예외가 잡히는지 여부를 나타내지 않기 때문이에요.
이 변수는 Perl 5.004에 추가됐어요.
$^W — 경고 스위치의 현재 값으로, -w를 썼으면 처음에 참이고 아니면 거짓이지만, 직접 수정할 수 있어요.
warnings도 보세요.
니모닉: -w 스위치와 관련.
${^WARNING_BITS} — use warnings 프래그마가 활성화한 현재 경고 검사 집합이에요. $^H와 %^H 변수와 같은 스코프를 가져요. 정확한 값은 warnings 프래그마에 내부적인 것으로 간주되며 Perl 버전 사이에 바뀔 수 있어요.
각 문장이 컴파일을 마칠 때마다 ${^WARNING_BITS}의 현재 값이 그 문장에 저장되고, 나중에 (caller($level))[9]로 검색할 수 있어요.
이 변수는 Perl v5.6.0에 추가됐어요.
$! — 참조될 때 $!은 C errno 정수 변수의 현재 값을 가져와요. $!에 숫자 값을 할당하면, 그 값이 errno에 저장돼요. 문자열로 참조될 때 $!은 errno에 대응하는 시스템 오류 문자열을 냅니다.
많은 시스템·라이브러리 호출은 실패하면 errno를 설정해 실패 원인을 나타내요. 성공하면 보통 errno를 0으로 설정하지 않으며 성공에도 0이 아닌 값을 설정할 수 있어요. 즉 errno, 따라서 $!은 실패 직후에만 의미가 있다는 뜻이에요:
if (open my $fh, "<", $filename) {
# Here $! is meaningless.
...
}
else {
# ONLY here is $! meaningful.
...
# Already here $! might be meaningless.
}
# Since here we might have either success or failure,
# $! is meaningless.
여기서 _의미가 없다_는 것은 $!이 open() 연산자의 결과와 무관할 수 있다는 뜻이에요. $!에 대한 할당도 마찬가지로 일시적이에요. die() 연산자를 호출하기 직전에 종료 값을 설정하거나, 오류 n 에 대응하는 시스템 오류 문자열을 검사하거나, $!을 의미 있는 상태로 복원하는 데 쓸 수 있어요.
Perl 자체는 시스템 호출이 수행되지 않아도 실패 시 errno를 0이 아닌 값으로 설정할 수 있어요.
니모닉: 방금 무엇이 펑 터졌나?
%! — %!의 각 요소는 $!이 그 값으로 설정됐을 때만 참 값을 가져요. 예를 들어 $!{ENOENT}는 $!의 현재 값이 ENOENT일 때, 즉 가장 최근 오류가 "No such file or directory"(또는 그것의 도덕적 등가물: 모든 운영 체제가 그 정확한 오류를 주진 않고, 확실히 모든 언어가 그런 것도 아님)일 때만 참이에요. 특정 참 값은 보장되지 않지만, 과거에는 일반적으로 $!의 숫자 값이었어요. 특정 키가 시스템에서 의미가 있는지 확인하려면 exists $!{the_key}를 쓰고, 유효한 키 목록은 keys %!을 쓰세요. 더 자세한 정보는 Errno를, "$!"도 보세요.
이 변수는 Perl 5.005에 추가됐어요.
$? — 마지막 파이프 close, 역따옴표(````````) 명령, wait()나 waitpid()의 성공적인 호출, 또는 system() 연산자가 반환한 상태예요. 이것은 전통적인 Unix wait() 시스템 호출이 반환하는 16비트 상태 단어일 뿐이에요(또는 그것처럼 보이게 만들어져요). 그래서 하위 프로세스의 종료 값은 실제로 ($? >> 8)이고, $? & 127은 프로세스가 죽은 원인이 된 시그널(있으면)을 주고, $? & 128은 코어 덤프가 있었는지 보고해요.
추가로 C에서 h_errno 변수가 지원되면, 어떤 gethost*() 함수가 실패하면 $?을 통해 그 값이 반환돼요.
SIGCHLD에 대한 시그널 핸들러를 설치했다면, $?의 값은 그 핸들러 밖에서는 보통 틀리게 돼요.
END 서브루틴 안에서 $?은 exit()에 주어질 값을 담아요. END 서브루틴에서 $?을 수정해 프로그램의 종료 상태를 바꿀 수 있어요. 예를 들어:
END {
$? = 1 if $? == 255; # die would make it 255
}
VMS에서 프래그마 use vmsish 'status'는 $?이 기본 POSIX 상태 에뮬레이션 대신 실제 VMS 종료 상태를 반영하게 해요. 자세한 내용은 perlvms의 "$?"를 보세요.
니모닉: sh와 ksh와 비슷.
$@ — 마지막 eval 연산자의 Perl 오류, 즉 마지막으로 잡힌 예외예요. eval BLOCK의 경우 실행 시간 오류 메시지이거나 die가 호출된 문자열 또는 참조예요. eval STRING 형태는 문법 오류와 다른 컴파일 시간 예외도 잡아요.
오류가 없으면 eval은 $@을 빈 문자열로 설정해요.
경고 메시지는 이 변수에 수집되지 않아요. 하지만 "%SIG"에 설명된 대로 $SIG{__WARN__}을 설정해 경고를 처리하는 루틴을 설정할 수 있어요.
니모닉: 오류가 "at" 어디에 있었나?
인터프리터 상태 관련 변수 (Variables related to the interpreter state)
이 변수들은 현재 인터프리터 상태에 대한 정보를 제공해요.
$^C — -c 스위치와 연관된 플래그의 현재 값이에요. 주로 -MO=... 와 함께 쓰여, 예를 들어 정상적인 지연 로딩 대신 컴파일 시간에 AUTOLOAD 하도록 컴파일될 때 코드가 자기 동작을 바꾸게 허용해요. $^C = 1 설정은 B::minus_c를 호출하는 것과 비슷해요.
이 변수는 Perl v5.6.0에 추가됐어요.
$^D — 디버깅 플래그의 현재 값이에요. 읽거나 설정할 수 있어요. 명령줄 등가물처럼 숫자나 기호 값을 쓸 수 있어요. 예: $^D = 10 또는 $^D = \"st\". perlrun의 " -D number"와 perlguts의 "인터프리터 실행 추적"을 보세요.
이 변수의 내용은 디버거 동작에도 영향을 줘요. perldebguts의 "Debugger Internals"를 보세요.
니모닉: -D 스위치의 값.
${^GLOBAL_PHASE} — perl 인터프리터의 현재 단계예요.
가능한 값들은:
CONSTRUCT — PerlInterpreter*가 perl_construct를 통해 구성되고 있어요. 이 값은 대부분 완전성을 위해 그리고 밑바탕 C 변수 PL_phase를 통한 사용을 위해 있어요. 인터프리터 구성이 끝나지 않으면 Perl 코드가 실행되는 것은 정말 불가능해요.
START — 이것은 전역 컴파일 시간이에요. 기본적으로 최상위 프로그램의 컴파일 시간 동안 직접 또는 간접적으로 실행된 모든 BEGIN 블록을 포함해요. BEGIN-블록과 혼동을 피하려고 이 단계를 "BEGIN"이라 부르지 않아요. BEGIN-블록은 최상위 프로그램뿐 아니라 어떤 컴파일 단위의 컴파일 시간 동안에도 실행되니까요. 런타임에 진입한 새롭고 지역화된 컴파일 시간, 예를 들어 eval \"use SomeModule\" 같은 구성으로 진입한 것은 전역 인터프리터 단계가 아니므로 ${^GLOBAL_PHASE}에 반영되지 않아요.
CHECK — 어떤 CHECK 블록의 실행.
INIT — "CHECK"와 비슷하지만, CHECK 블록이 아니라 INIT-블록에 대한 것.
RUN — main 실행 시간, 즉 PL_main_root의 실행.
END — 어떤 END 블록의 실행.
DESTRUCT — 전역 파괴.
UNITCHECK-블록에 대한 값은 없다는 점도 유의하세요. 그것들은 각 컴파일 단위마다 개별적으로 실행되므로 전역 인터프리터 단계가 아니기 때문이에요.
모든 프로그램이 가능한 각 단계를 거쳐야 하는 것은 아니지만, 한 단계에서 다른 단계로의 전환은 위 목록에 설명된 순서로만 일어날 수 있어요.
Perl 코드가 볼 수 있는 모든 단계의 예:
BEGIN { print "compile-time: ${^GLOBAL_PHASE}\n" }
INIT { print "init-time: ${^GLOBAL_PHASE}\n" }
CHECK { print "check-time: ${^GLOBAL_PHASE}\n" }
{
package Print::Phase;
sub new {
my ($class, $time) = @_;
return bless \$time, $class;
}
sub DESTROY {
my $self = shift;
print "$$self: ${^GLOBAL_PHASE}\n";
}
}
print "run-time: ${^GLOBAL_PHASE}\n";
my $runtime = Print::Phase->new(
"lexical variables are garbage collected before END"
);
END { print "end-time: ${^GLOBAL_PHASE}\n" }
our $destruct = Print::Phase->new(
"package variables are garbage collected after END"
);
이것은 이렇게 출력해요.
compile-time: START
check-time: CHECK
init-time: INIT
run-time: RUN
lexical variables are garbage collected before END: RUN
end-time: END
package variables are garbage collected after END: DESTRUCT
이 변수는 Perl 5.14.0에 추가됐어요.
$^H — 경고: 이 변수는 엄격히 내부 전용이에요. 그 가용성, 동작, 내용은 예고 없이 바뀔 수 있어요.
이 변수는 Perl 인터프리터를 위한 컴파일 시간 힌트를 담아요. BLOCK의 컴파일이 끝날 때 이 변수의 값은 인터프리터가 BLOCK 컴파일을 시작할 때의 값으로 복원돼요.
각 문장이 컴파일을 마칠 때마다 $^H의 현재 값이 그 문장에 저장되고, 나중에 (caller($level))[8]로 검색할 수 있어요. perlfunc의 "caller EXPR"을 보세요.
perl이 어휘 스코프를 제공하는 어떤 블록 구성(eval 본문, require된 파일, 서브루틴 본문, 루프 본문, 조건 블록 등)을 파싱하기 시작할 때, $^H의 기존 값은 저장되지만 그 값은 변경되지 않은 채 남아요. 블록 컴파일이 완료되면 저장된 값을 되찾아요. 값이 저장되고 복원되는 지점 사이에서, BEGIN 블록 안에서 실행되는 코드는 $^H의 값을 자유롭게 바꿀 수 있어요.
이 동작은 어휘 스코프의 의미론을 제공하며, 예를 들어 use strict 프래그마에서 쓰여요.
내용은 정수여야 해요. 서로 다른 비트가 서로 다른 프래그마 플래그에 쓰여요. 예시:
sub add_100 { $^H |= 0x100 }
sub foo {
BEGIN { add_100() }
bar->baz($boon);
}
BEGIN 블록 실행 중에 무슨 일이 일어나는지 고려해 보세요. 이 시점에서 BEGIN 블록은 이미 컴파일됐지만, foo()의 본문은 여전히 컴파일 중이에요. 따라서 $^H의 새 값은 foo()의 본문이 컴파일되는 동안에만 보일 거예요.
BEGIN { add_100() } 블록을 이것으로 치환하면:
BEGIN { require strict; strict->import('vars') }
use strict 'vars'가 어떻게 구현되는지 보여 줘요. 같은 어휘 프래그마의 조건부 버전이 여기 있어요.
BEGIN {
require strict; strict->import('vars') if $condition
}
이 변수는 Perl 5.003에 추가됐어요.
%^H — %^H 해시는 $^H와 같은 스코프 의미론을 제공해요. 이것은 어휘적으로 스코프된 프래그마를 구현하는 데 유용하게 해 줘요. perlpragma를 보세요. 런타임에 접근할 때 모든 항목이 문자열화되므로, 단순한 값만 수용할 수 있어요. 예를 들어 객체에 대한 참조는 안 된다는 뜻이에요.
각 문장이 컴파일을 마칠 때마다 %^H의 현재 값이 그 문장에 저장되고, 나중에 (caller($level))[10]으로 검색할 수 있어요. perlfunc의 "caller EXPR"을 보세요.
%^H에 항목을 넣을 때, 해시의 다른 사용자와 충돌하는 것을 피하기 위해 어떤 키를 쓸지에 대한 관례가 있어요. 모듈은 그 모듈의 이름(main 패키지의 이름)과 "/" 문자로 시작하는 키만 써야 해요. 예를 들어 Foo::Bar 모듈은 Foo::Bar/baz 같은 키를 써야 해요.
이 변수는 Perl v5.6.0에 추가됐어요.
${^OPEN} — PerlIO가 쓰는 내부 변수예요. \\0 바이트로 구분된 두 부분의 문자열로, 첫 부분은 입력 레이어를, 두 번째 부분은 출력 레이어를 설명해요.
이것은 open 프래그마의 어휘 효과와, -C 명령줄 스위치와 PERL\_UNICODE 환경 변수의 io 또는 D 옵션의 main 프로그램 스코프 효과를 적용하는 메커니즘이에요.
accept(), open(), pipe(), readpipe()(관련 qx와 STRING 연산자 포함), socket(), socketpair(), sysopen() 함수는 이 변수의 어휘 값의 영향을 받아요. 전달된 파일 이름에 대해 readline()(또는 관련 <>(다이아몬드)와 <<>>(이중 다이아몬드) 연산자)이 여는 암시적 "ARGV" 핸들도 영향을 받아요(단 STDIN을 여는 경우는 아님). 이 변수가 설정되지 않으면, 이 함수들은 PerlIO의 "Defaults and how to override them"에 설명된 기본 레이어를 설정할 거예요.
open()은 3개의 인자로 호출되고 명시적 레이어가 지정되면 이 변수(와 기본 레이어)를 무시해요. IO::Handle 같은 모듈을 통한 이 함수들의 간접 호출은 다른 어휘 스코프에서 발생하므로 영향을 받지 않아요. opendir()가 여는 것 같은 디렉터리 핸들은 현재 영향을 받지 않아요.
이 변수는 Perl v5.8.0에 추가됐어요.
$^P — 디버깅 지원을 위한 내부 변수예요. 각 비트의 의미는 바뀔 수 있지만, 현재는 다음을 나타내요.
0x01 — 서브루틴 enter/exit 디버그.
0x02 — 줄 단위 디버깅. 실행되는 각 문장에 대해 DB::DB() 서브루틴이 호출되게 해요. 소스 코드 줄의 저장(0x400처럼)도 일으켜요.
0x04 — 최적화 끄기.
0x08 — 향후 대화형 검사를 위해 더 많은 데이터 보존.
0x10 — 서브루틴이 정의된 소스 줄에 대한 정보 유지.
0x20 — single-step을 켠 상태로 시작.
0x40 — 보고 시 이름 대신 서브루틴 주소 사용.
0x80 — goto &subroutine도 보고.
0x100 — 컴파일된 위치에 기반해 eval에 대한 유용한 "file" 이름 제공.
0x200 — 컴파일된 위치에 기반해 익명 서브루틴에 유용한 이름 제공.
0x400 — 소스 코드 줄을 @{\"_<$filename\"}에 저장.
0x800 — 소스를 저장할 때 서브루틴을 생성하지 않는 eval 포함.
0x1000 — 소스를 저장할 때 컴파일되지 않은 소스 포함.
일부 비트는 컴파일 시간에만, 일부는 실행 시간에만 관련될 수 있어요. 이것은 새 메커니즘이고 세부 사항은 바뀔 수 있어요. perldebguts도 보세요.
${^TAINT} — taint 모드가 켜져 있는지 꺼져 있는지 반영해요. 1은 켜짐(프로그램이 -T로 실행됨), 0은 꺼짐, -1은 taint 경고만 활성화됐을 때(-t나 -TU로).
참고: taint 지원 없이 빌드된 perl(perlsec 참조)이라면, ${^TAINT}는 프로그램이 -T로 실행됐어도 항상 0일 거예요.
이 변수는 읽기 전용이에요.
이 변수는 Perl v5.8.0에 추가됐어요.
${^SAFE_LOCALES} — 이 perl에 안전한 로케일 연산이 가능한지(값 1) 또는 불가능한지(값 0) 반영해요. 이 변수는 perl이 스레드 없이 컴파일됐으면 항상 1이에요. 이 perl이 스레드 안전 로케일 연산을 쓰고 있어도 1이에요. 개별 스레드는 perlapi의 "switch\_to\_global\_locale"를 호출해 전역 로케일(일반적으로 불안전)을 선택할 수 있다는 점을 유의하세요. 이 변수는 그러한 스레드에서도 현재 여전히 1로 설정돼요.
이 변수는 읽기 전용이에요.
이 변수는 Perl v5.28.0에 추가됐어요.
${^UNICODE} — Perl의 특정 Unicode 설정을 반영해요. 가능한 값에 대한 자세한 정보는 perlrun의 -C 스위치 문서를 보세요.
이 변수는 Perl 시작 중에 설정되고 이후에는 읽기 전용이에요.
이 변수는 Perl v5.8.2에 추가됐어요.
${^UTF8CACHE} — 이 변수는 내부 UTF-8 오프셋 캐싱 코드의 상태를 제어해요. 1은 켜짐(기본), 0은 꺼짐, -1은 모든 결과를 선형 스캔과 대조해 확인하고 어떤 불일치든 공황 상태를 내는 캐싱 코드 디버그.
이 변수는 Perl v5.8.9에 추가됐어요. 예고 없이 바뀌거나 제거될 수 있지만, 현재는 다중 바이트 UTF-8 인코딩 문자의 경계를 다시 계산하지 않도록 하는 데 쓰여요.
${^UTF8LOCALE} — 이 변수는 시작 시 perl이 UTF-8 로케일을 감지했는지 여부를 나타내요. 이 정보는 perl이 로케일에 UTF-8성을 맞추는 조정 모드일 때(-CL 명령줄 스위치로 실행될 때처럼) 사용돼요. 이에 대한 더 많은 정보는 perlrun을 보세요.
이 변수는 Perl v5.8.8에 추가됐어요.
폐기 및 제거된 변수 (Deprecated and removed variables)
변수를 폐기하는 것은 perl 유지보수자들이 결국 그 변수를 언어에서 제거할 의도를 발표하는 것이에요. 상태에도 불구하고 여전히 사용할 수는 있을 거예요. 폐기된 변수를 쓰면 경고가 발생해요.
변수가 제거되면, 그 사용은 그 변수가 지원되지 않는다는 오류를 발생시켜요.
오류 메시지에 대한 자세한 내용은 perldiag을 보세요.
$# — $#은 인쇄된 숫자를 포맷하는 데 쓸 수 있는 변수였어요. 폐기 주기 후 그 마법은 Perl v5.10.0에서 제거됐고, 이제 쓰면 컴파일 오류가 발생해요: $# is no longer supported.
이것은 배열 이름 앞에 넣어 마지막 인덱스를 얻는 $#array 같은 기호가 아니에요. 그건 여전히 Perl에서 배열의 마지막 인덱스를 얻는 방법이에요. (perlintro의 "Arrays" 참조.) 둘은 서로 아무 관련이 없어요.
Perl 5에서 폐기됨.
Perl v5.10.0에서 제거됨.
$\* — $*은 다중 줄 매칭을 활성화하는 데 쓸 수 있는 변수였어요. 폐기 주기 후 그 마법은 Perl v5.10.0에서 제거됐어요. 이제 쓰면 컴파일 오류가 발생해요: $* is no longer supported. 대신 /s와 /m regexp 수정자를 써야 해요.
Perl 5에서 폐기됨.
Perl v5.10.0에서 제거됨.
$[ — 이 변수는 배열의 첫 요소, 부분 문자열의 첫 문자의 인덱스를 저장해요. 기본값은 0이지만, 이론적으로 1로 설정해 Perl이 첨자할 때와 index() 및 substr() 함수를 평가할 때 awk(또는 Fortran)처럼 더 행동하게 할 수 있었어요.
Perl 릴리스 5부터 $[에 대한 할당은 컴파일러 지시문으로 취급되며, 다른 파일의 동작에 영향을 줄 수 없어요. (그래서 컴파일 시간 상수만 할당할 수 있어요.) 그 사용은 매우 권장되지 않아요.
Perl v5.10.0 이전에는 $[에 대한 할당이 strict 같은 다른 컴파일 시간 지시문과 달리 같은 파일의 바깥 어휘 스코프에서 보일 수 있었어요. 그것에 local()을 쓰면 그 값이 엄격히 어휘 블록에 묶였어요. 이제는 항상 어휘적으로 스코프돼요.
Perl v5.16.0부터 arybase 모듈이 구현해요.
Perl v5.30.0부터, 또는 use v5.16 아래에서, 또는 no feature \"array_base\"로 $[은 더 이상 효과가 없고 항상 0을 담아요. 0을 할당하는 것은 허용되지만, 다른 값이면 오류를 발생해요.
니모닉: \[ 은 첨자를 시작한다.
Perl v5.12.0에서 폐기됨.
${^ENCODING} — 이 변수는 더 이상 지원되지 않아요.
소스 코드를 Unicode로 변환하는 데 쓰인 Encode 객체에 대한 객체 참조 를 담곤 했어요.
그 목적은 비-ASCII Perl 스크립트가 UTF-8로 쓰일 필요가 없게 하는 것이었어요. 이것은 UTF-8 인코딩 텍스트에서 작동하는 편집기가 흔해지기 전에 유용했지만, 아주 오래전 일이에요. 그것은 기대하지 않던 다른 모듈의 동작에 영향을 주는 등 문제를 일으켜 일반적인 혼란을 야기했어요.
이런 기능이 필요하다면 Filter::Encoding 같은 간단한 소스 필터를 쓰는 것이 권장돼요.
누군가의 이 변수 사용 때문에 당신의 코드가 나쁜 영향을 받아 여기 온 거라면, 보통 망가지는 함수의 시작 부분 근처에서 이렇게 해서 우회할 수 있어요.
local ${^ENCODING};
이것은 포함 함수의 실행 스코프 동안 변수를 undefine해요.
이 변수는 Perl 5.8.2에 추가되고 5.26.0에서 제거됐어요. undef 외의 다른 값으로 설정하는 것은 Perl 5.28.0에서 치명적으로 만들었어요.
${^WIN32_SLOPPY_STAT} — 이 변수는 더 이상 기능이 없어요.
이 변수는 Perl v5.10.0에 추가되고 Perl v5.34.0에서 제거됐어요.