죽은 프로그램은 거짓말을 하지 않는다

Posted by epicdev Archive : 2011. 10. 3. 11:50
프로그래밍을 하다보면 '그런 일은 절대 일어날 리 없어'라는 사고에 빠지기 쉽다. 우리 중 대다수는 파일이 성공적으로 닫혔는지, 혹은 트레이스문이 우리가 예상한 대로 찍히는지 확인하지 않는 코드를 작성한 경험이 있다. 그리고 다른 모든 조건이 동일하다면, 그럴 필요가 없었을지도 모른다. 문제의 코드는 정상 조건 하에서는 실패하지 않았을 것이다. 하지만 우리는 지금 방어적으로 코딩하고 있다.

모든 에러는  정보를 준다. 여러분은 에러가 발생할 리 없다고 스스로를 설득하고선 그걸 무시하기로 할 수 있다. 반면에 실용주의 프로그래머는 만약 에러가 있다면 정말로 뭔가 나쁜 일이 생긴 것이라고 자신에게 이야기한다.

<실용주의 프로그래머 팁>
일찍 작동을 멈추게 하라

망치지 말고 멈추라

가능한 한 빨리 문제를 발견하게 되면, 좀 더 일찍 시스템을 멈출 수 있다는 이득이 있다. 게다가 프로그램을 멈추는 것이 할 수 있는 최선일 때가 많다.

자바 언어와 라이브러리는 이 철학을 포용했다. 런타임 시스템에서 뭔가 예상하지 못한 것이 발생하면 RuntimeException을 던진다. 만약 이 예외가 catch되지 않으면 프로그램의 최상위 수준까지 스며 나올 것이고, 결국 스택 트레이스를 출력하며 프로그램을 멈춰버릴 것이다.

다른 언어에서도 똑같이 할 수 있다. 예외 처리가 지원되지 않거나 라이브러리가 예외를 던지지 않으면, 여러분 자신이 직접 에러를 처리해야 한다. C에서는 매크로가 이 작업에 매우 유용할 것이다.
#define CHECK(LINE, EXPECTED) \
    { int rc = LINE; \
    if (rc != EXPECTED) \
        ut_abort(__FILE__, __LINE__, #LINE, rc, EXPECTED); }

void ut_abort(char* file, int ln, char* line, int rc, int exp) {
    fprintf(stderr, "%s line %d\n'%s': expected %d, got %d\n",
        file, ln, line, exp, rc);
    exit(1);
}

그러면 다음을 사용해서 결코 실패하면 안 되는 호출을 감쌀 수 있다.

check(stat("/tmp", &stat_buff), 0);

만약 실패한다면, stderr에 다음과 같은 메시지가 출력될 것이다.

source.c line 19
'stat("/tmp", &stat_buff)': expected 0, got -1

분명히 실행 중인 프로그램을 그냥 종료해 버리는 것은 때로 적절치 못하다. 해제되지 않은 자원이 남아 있을 수도 있고, 로그 메시지를 기록 할 필요가 있을 수도 있고, 열려있는 트랜잭션을 청소해야 하거나, 다른 프로세스들과 상호작용해야 할 필요가 있을지도 모른다. 그렇지만 기본 원칙은 똑같다. 방금 불가능한 뭔가가 발생했다는 것을 코드가 발견한다면, 프로그램은 더 이상 유효하지 않다고 할 수 있다. 이 시점 이후로 하는 일은 모두 수상쩍은 게 된다. 되도록 프로그램을 빨리 종료해야 할 일이다. 일반적으로, 죽은 프로그램이 입히는 피해는 절름발이 프로그램이 끼치는 것보다 훨씬 덜한 법이다.

 
실용주의프로그래머
카테고리 컴퓨터/IT > 프로그래밍/언어
지은이 앤드류 헌트 (인사이트, 2007년)
상세보기

'Archive' 카테고리의 다른 글

리소스의 할당과 해제  (0) 2011.10.03
예외는 예외적인 문제에 사용하라  (0) 2011.10.03
타인의 버그를 대하는 자세  (0) 2011.10.02
GUI와 쉘  (0) 2011.10.02
예광탄 코드와 프로토타이핑의 차이점  (0) 2011.10.02