2017-04-09 1 views
7

아마도 내 진짜 질문은 "이 기능은 Perl 학습에 적합합니까?"입니까? Should this Perl 6 CATCH block be able to change variables in the lexical scope?을 기반으로하면 가장 간단한 예가 간단한 예를 넘어서는 것 같습니다.언제 펄 6 예외를 다시 시작하겠습니까?

그런 질문에서 문제를 해결하기보다는 기능을 가지고 놀고 있었기 때문에 그 특정 문제에 대해 다른 방식으로 어리석은 또는 더 나은 것으로 보이는 무언가로 작업하고있었습니다.

경고의 문서화 된 사용이 특별한 종류의 예외 ("예외 제어")로되어있어 메시지를 받고, 원한다면 그것을 잡을 수 있지만, 무시할 수 있으며, 독자적으로 재개 할 수 있습니다 (비록 내가 이것은 Where should I catch a Perl 6 warning control exception?에서 다소 어리 석다.)

그 외에도 호출자가 호출 수신자가 호출 수신자의 범위 밖에서 오류를 처리 할 수있는 것에 대해 생각하고 있습니다. 예를 들어, 데이터베이스에 다시 연결하고, 누락 된 디렉터리를 수정하고, 호출 수신자가 책임지지 않는 기타 외부 리소스 문제를 해결합니다.

"현실 세계"프로그래밍 사람들은 실제로 문제를 처리하지 않는 경향이 있기 때문에 다른 언어에서 이런 종류의 일에 대해 읽는 데 조언은 주로 사용하지 않는 것이 좋습니다.

C# exception handler resume next에 대한 대답은 불량한 연습과 추악한 코드라고합니다. 나는 분명히 피 호출자에게 많은 코드를 숨기는 방법을 찾지 못했습니다.

초보자에게 권장할만한 방법이라고 확신하지는 않지만이 예제를 해킹했습니다. 프로그램이 시작될 때 PID 파일을 찾습니다. 하나를 찾으면 예외를 던집니다. 이 예외를 처리하면 다른 인스턴스가 아직 실행 중인지 여부가 검사되므로 다른 유형의 예외가 발생할 수 있습니다. 그리고 파일 IO 문제를 처리 할 수있는 방법이 있습니다. 그 트릭은 X::MyProgram::FoundSemaphore이 다른 프로그램이 실행 중이 아닐지라도 (PID 파일을 남겨둔 채로) 다시 시작할 수 있다는 것입니다.

+1

질문에는 중요하지 않지만 'BEGIN'은 컴파일 할 때 실행된다는 점에 유의하십시오. 모듈은 설치시 컴파일되므로 모듈에 배치 된이 코드는 의도 한대로 작동하지 않을 수 있습니다. 'INIT'는 프로그램 시작에있어 더 나은 선택이 될 것이며, 모듈의 경우에 잘 작동 할 것입니다. –

+0

네, INIT가 더 좋아 보입니다. –

답변

6

재개 예외는 확실히 펄 6에 나는 전혀 아직 "사용자 공간"코드에서 사용했습니다 생각하지 않습니다에 대한 나 자신에 도달 발견 한 것이 아니다. 재개 가능한 예외가 supplyreact 블록에 사용 된 emit 함수를 구현하는 올바른 방법으로 밝혀졌습니다. gather에서 사용되는 take 함수도 재개 가능한 예외를 사용하여 구현되며 이미 발견 한 것처럼 warn에서 사용합니다.

일반적인 Perl 6 사용자가 관심을 가질만한 유일한 케이스는 warn입니다. 경고를 캡처하여 다른 곳으로 보내면 (아마도 로그 파일이나 로그 서버에) 상당히 합리적인 일입니다. 할 필요가. Learning Perl 6이가는 한, 재개 가능한 예외의 명백한 예가 될 것입니다.

Perl 6 자체에서 재개 가능한 예외를 이용하는 모든 유스 케이스가 "제어 예외"로 분류되는 것이 중요하다고 생각합니다. 제어 예외는 구현 레벨에서 본질적으로 예외가되는 예외입니다. 즉, 제어의 비 로컬 전송이 관련됩니다. 그들은 당신의 emit, take, warn, next, last 경우 펄 6을 사용하는 것이 오히려 어색 때문에 언어 수준에서 독특한 만들어 등등 default가 제어 예외를 삼키는 때문에 CATCH 블록의 작동이 중지된다!

그러나 "do not I say, do not I do": Perl 6은 비 로컬 흐름 제어를 구현하기 위해 예외 시스템을 사용하기 때문에 기쁜 일이지만 다소 먼지가 많은 곳에서 할 일의 예로서 그것을 들고 있기보다는 언어의 그리고 좋은 이유가 있습니다 : 일반적으로 예외를 사용하여 흐름 제어를 수행하는 코드는 추적하기가 어려우며 재개 가능한 예외의 경우에는 두 배가됩니다. 다른 큰 위험은 베어 try 또는 CATCHdefault을 사용하는 코드로 이러한 예외를 삼킬 수 있다는 것입니다. 더 큰 코드베이스에서 처리하는 것이 상당히 허술합니다.

재시작 예외의 가장 좋은 용도는 사용자가 전혀 예외적으로 생각하지 않는 것에 대한 구현 전략으로 밝혀 질 것입니다. takeemit (및 , 대부분의 시간, warn). 그리고 재개 가능한 예외의 기존 사례와 마찬가지로 재개되는 것은 재개 가능한 상황에서 던져 지도록 특별히 고안된 예외 유형이며이를 수행하는 것이 합당한 경우에만 사용됩니다. Perl 6이 사용자 정의 컨트롤 예외를 정의 할 수있는 방법을 제공 할 때까지는 이렇게하기를 꺼려합니다. try/default 삼키는 문제로 인해 너무 부서지기 쉽습니다.

+0

$ * ARGFILES가 잘못된 파일을 발견하여 재개 가능한 예외를 사용하는 사례 : https://stackoverflow.com/questions/48865412/how-should-i-handle-perl-6-argfiles-that-cant-be-read 바이 라인 –

관련 문제