2009-11-04 1 views
14

나는 그들 모두가하는 일을 알고 있지만, 내가 필요로하는 상황에서는 자신을 찾지 못했다. 나는 많은 경우에 BEGIN 블럭을 사용했고, 한동안은 END을 사용했다. BEGIN은 코드를 실행하기 전에 환경을 조정해야 할 때 특히 유용하며 추적하기 어려운 치명적인 오류에 대한 중요한 상태 정보를 트래핑하기 위해 특정 디버깅 상황에서 END을 사용했습니다.Perl에서 CHECK, UNITCHECK 및 INIT 블록의 유용성은 무엇입니까?

CHECK, UNITCHECK 또는 INIT을 사용한 적이 있습니까? 그렇다면 무엇을 위해서입니까? 그리고 BEGIN 블록이 어떤 이유로 sufficed하지 않았습니까?

블록 설명서는 PerlDoc입니다.

답변

5

나는 약간의 중용량 처리를 수행 할 import 기능을 가지고 있었고 eval 전화를 걸었다. 어떻게 그런 식으로 디버깅합니까? 모듈이 use 모듈을 컴파일 할 때 가져 오기 기능이 실행됩니다 (BEGIN 블록 안에있는 것처럼). 웬일인지 (나는 그것이 heredoc 표기법을 사용하여 import에 매개 변수를 전달해야했기 때문에 그런 것 같았지만 다른 것일 수도 있음) require Module; Module->import(@args)을 말할만큼 충분하지 않았습니다.

그래서 제 해결 방법은 eval의 문자열을 import에 작성하고 다른 변수를 저장하는 것이 었습니다. 그런 다음 블록에서 eval을 실행했습니다. 디버거를 실행할 때 첫 번째 실행 지점이 INIT 블록의 시작 부분에 있었고 디버거를 사용하여 eval 문을 단계별로 실행할 수있었습니다.

+0

이제'require Module; module-> import (@stuff)'를하고 싶지 않은 이유를 기억합니다. 이미 디버깅 할 수있는 테스트 스크립트 세트가 있었기 때문에 모든 파일에서'모듈 사용 '문을 편집하고 싶지 않았기 때문입니다. – mob

+9

컴파일 타임 코드를 디버깅하기 위해 이러한 왜곡을 수행 할 필요가 없습니다. 소스에 $ DB :: single = 1을 넣으면 디버거는 프로그램을 처리하는 단계와 관계없이 그 시점에서 중단됩니다. (http://perldoc.perl.org/perldebug.html#Debugging 참조) -compile-time-statements) –

+0

감사합니다. Brian! 그거 알아두면 좋을거야. – mob

7

재미있는 CHECK 블록의 사용법은 1 장의 Simon Cozens (O'Reilly)의 "고급 Perl 프로그래밍", "나중에 CHECK 수행하기"섹션에 나와 있습니다. 그는 "최종"java와 유사한 속성을 구현하는 방법을 보여줍니다.

또한 Devel :: Sub :: Trace는 INIT 블록을 사용하여 추적을 생성합니다 (이 정보는 Devel :: Hook의 POD에서 가져온 것입니다. 그 이름을 가진 블록)

+0

또한 필자는 결코 시도하지 않았지만 몇 가지 흥미로운 조롱 접근법에 대해 이러한 것들을 활용할 수도 있습니다. 누군가가 아이디어를 가지고 있다면이 가능성을 별도의 대답으로 확장 할 수 있습니다. – DVK

3

글쎄 BEGIN 블록은 컴파일 타임에 실행됩니다. 따라서 코드를 가져 와서 모듈을 가져 오기 위해 실행해야합니다.

몇 백 개의 스크립트에서 발생하는 상용구 코드에서 수행되는 모든 작업을 수행하기 위해 스크립트 래퍼를 작성했습니다.

  • 모듈 읽기가 use-d 일 때해야 할 일이있었습니다. 내가 BEGIN 블록과 import sub로 달렸다.
  • 그러나 은 스크립트가 사용할 서비스 인으로 초기화 된 모든 보일러 플레이트가 있습니다. 따라서 INIT 블록에서 이러한 작업을 실행했습니다.
  • END 블록에서 필요한 정리 및 종료 코드를 실행하십시오.

XS 엔진을 사용하여 모듈을 작성하면 CHECK가 도움이 될 것이라고 생각하지만, 소수의 경우에만 사용했습니다. 한 번 생각해 보면 중급 Perl에있는 제안을 확인하는 것이 었습니다. 그리고 나는 다른 이유들을 기억할 수 없다.

그러나 코드를 스크립트의 일부로 생각하면 모듈을 설정하는 것보다 INIT 블록을 사용합니다. 본질적으로, 나는 컴파일 시간 동안 필요한 것만 수행한다.

+0

Axeman - 초기화의 경우, INIT 블록이 일반 프로그램의 시작 부분에 init 코드를 배치하여 얻을 수없는 특별한 것을 제공하는 용도를 명확하게 설명해 주시겠습니까? 시각화/유지 보수가 용이 한가요? – DVK

+1

@DVK : 클래스 초기화를 수행하기 위해 모듈에서 INIT 블록을 사용했습니다. 사용자는 그런 종류의 일에 대해 알 필요가 없습니다. 불행히도 PAR :: Packer는 예약 된 블록 (특히 INIT 및 CHECK)에 문제가 있으므로이 방법으로 배포 할 수있는 모듈에서는 작동하지 않습니다. 보통 INIT 블록을 리핑하여 결국 생성자가 처음 호출 될 때 호출되는'initialize()'서브을 선호하게됩니다. –

+0

CHECK 블록은 XS 모듈과 아무 관련이 없습니다. – rurban

1

perlmod를BEGINEND 일반적으로 사용되는 참으로 그 특별한 블록 만 설명합니다. 그들은 단지 CV, LIFO 또는 FIFO의 배열입니다. 이러한 블록은 코드가 실행될 때 소스 파일의 위치와 관계없이 별도의 타이밍을 허용합니다. 따라서 코드 섹션을 함께 유지할 수 있지만 서로 다른 시간에 실행됩니다 (PHASES).

CHECK 모듈 초기화 (사용 패키지) 후 고정 된 순서에 컴파일러 스위트 O (-MO=C...)를 실행하기 위해 초기에 첨가하고, 메인 프로그램하기 전에 실행 컨텍스트가 수를 저장합니다. 이것은 실행 시간 (after)과 컴파일 시간 (before)을 구분합니다. perl -c가 CHECK 후에 중지됩니다.

저는 컴파일러의 관리자이기 때문에 CHECK와 -MO =를 광범위하게 사용합니다. 내 모듈 compile() 메서드는 O에 의해 CHECK 블록 내에 호출됩니다. Od (디버깅 O) 나는 compile 메서드를 CHECK가 아니라 나중에 INIT라고 부르므로 디버거가이 메서드를 호출합니다. 디버거는 기본적으로 CHECK 블록을 실행하지 않으므로 $DB::single=1으로 강제 실행하거나 Od을 사용해야합니다.

UNITCHECK은 나중에 미세 입자 모듈 컴파일 및로드에 추가되었습니다. .pmc 파일.

나는 지금까지 그것을 사용한 적이 없습니다. 그것은 또한 런타임에 발생할 수 있으므로 런타임에로드 된 모듈의 유형 검사에 사용할 수 있습니다.

INIT을 추가하여 별도의 클래스 초기화를 허용했습니다.

거의 사용하지 않지만 편리합니다.

+0

"CHECK, UNITCHECK 또는 INIT를 사용한 적이 있습니까? 그렇다면 BEGIN 블록이 어떤 이유로 충분하지 않았습니까?" 그런 얇은 설명의 종류, OP는 어디서나 얻을 수 있습니다. – Axeman

관련 문제