화면에서 캐릭터 발이 바닥에 제대로 닿는지 확인하는 작업을 하고 있었다. 원인을 찾으려고 진단 코드를 넣고 다시 돌렸다. 아무 변화가 없었다.
이상했다. 코드를 다시 확인했다. 잘 들어가 있었다. 또 돌렸다. 또 그대로였다.
엉뚱한 데를 두 번 팠다
여기서 다른 원인들을 의심하기 시작했다. 하위 프로그램이 안 뜨나, 시간 제한에 걸리나. 그렇게 두 번 연속 실패하면서 시간을 태웠다.
그러다 파일 시각을 봤다. 내가 고친 코드는 6시 04분. 그런데 화면이 실제로 읽는 파일은 5시 22분이었다.
이 프로젝트는 여러 소스를 하나로 묶어서 화면에 올린다. 그러니 소스를 고쳐도 묶는 작업을 다시 하지 않으면 화면은 42분 전 코드를 계속 읽는다. 페이지는 멀쩡히 돌아간다. 새로 넣은 것만 없다.
제일 헷갈리는 종류의 증상이다
이게 고약한 이유는 에러가 없기 때문이다. 실패했다고 말해주면 원인을 찾는다. 그런데 이건 “고쳤는데 안 변한다”로 나타난다. 그러면 사람은 자기 코드가 틀렸다고 생각하고 맞는 코드를 계속 고친다. 고칠수록 멀어진다.
그래서 순서를 정했다. “고쳤는데 동작이 안 변한다” 소리가 나오면, 제일 먼저 결과물 파일과 소스 파일의 시각을 대조한다. 코드 내용을 들여다보는 건 그다음이다. 이 검사는 10초면 끝난다.
수정의 끝을 다시 정의했다
더 근본적으로는 “수정 완료”의 정의가 틀려 있었다. 나는 소스를 저장하면 고친 거라고 생각했다. 실제로는 다시 묶는 것까지가 수정이다.
그래서 작업 절차에 그 단계를 명시적으로 넣었다. 빼먹으면 다음에 또 42분 전 코드를 보면서 멀쩡한 걸 고치고 있을 테니까.
재발방지 체크리스트
① “고쳤는데 안 변함” 증상은 결과물 vs 소스 시각 대조가 1순위다. 코드 내용은 그다음.
② 묶어서 서빙하는 구조라면 다시 묶는 것까지가 수정이다. 절차에 넣는다.
③ 에러 없이 옛 것이 계속 나오는 상태를 의심 목록에 올린다. 조용해서 제일 오래 헤맨다.
④ 같은 증상으로 두 번 실패하면 접근을 바꾼다. 세 번째도 같은 자리를 파면 원인은 다른 데 있다.
① “고쳤는데 안 변함” 증상은 결과물 vs 소스 시각 대조가 1순위다. 코드 내용은 그다음.
② 묶어서 서빙하는 구조라면 다시 묶는 것까지가 수정이다. 절차에 넣는다.
③ 에러 없이 옛 것이 계속 나오는 상태를 의심 목록에 올린다. 조용해서 제일 오래 헤맨다.
④ 같은 증상으로 두 번 실패하면 접근을 바꾼다. 세 번째도 같은 자리를 파면 원인은 다른 데 있다.