Perl에서는 코드 실행 시간을 제어할 수 있는 특별한 블록(BEGIN, CHECK, INIT, END)이 존재합니다:
BEGIN { ... } — 파일이 컴파일될 때 즉시 실행됨(주 코드 및 모듈 로드 전);CHECK { ... } — 모든 파일이 컴파일된 후이지만 실행 전(모든 버전의 Perl에서 지원되지 않음);INIT { ... } — 주 코드 실행 전에 실행됨("runtime");END { ... } — 프로그램이 종료된 후, 스크립트를 나오면서 실행됨.실행 순서:
BEGINCHECKINITEND예제:
BEGIN { print "BEGIN executed "; } CHECK { print "CHECK executed "; } INIT { print "INIT executed "; } print "Main code executed "; END { print "END executed "; }
모듈 내부의 BEGIN 블록이 use가 아닌 require를 통해 모듈이 연결되었을 때 프로그램의 전역 상태에 영향을 미칠 수 있습니까?
답변 및 예제:
BEGIN 블록은 컴파일 시 실행되므로, 모듈이 require를 통해 연결되는 경우(컴파일 시가 아닌 실행 시), 수행되지 않으며, use를 통해 연결될 때(포함 파일에서 컴파일 중 실행됨)만 수행됩니다. 이는 초기화가 BEGIN에 의존하는 경우 예상치 못한 동작을 초래할 수 있습니다.
이야기 1: 한 프로젝트에서 환경 변수를 초기화하기 위해
BEGIN이 사용되었고, 모듈이require를 통해 연결되었으며, 그 결과로 변수들이 설정되지 않아 프로덕션에서 구성 로딩에 혼란이 발생했습니다.
이야기 2: 파일 디스크립터를 닫기 위해
END블록을 사용할 때 프로세스의 암묵적인 정지를 고려하지 않았습니다; 때때로END블록이 Perl 인터프리터의 비정상 종료로 인해 실행되지 않아 로그에서 데이터가 손실되었습니다.
이야기 3:
CHECK블록은 환경 유효성을 검사하는 유일한 장소였습니다. 사용자가 구 버전의 Perl에서 스크립트를 실행했을 때CHECK블록이 없어서 검사가 수행되지 않았고, 이로 인해 생산 환경에서 심각한 결함이 발생했습니다.