한 셀에 여러 종류의 문자가 섞여 있는 자료에서 원하는 종류만 골라내는 함수를 쓰고 있었다. 문자열을 한 글자씩 돌면서 조건에 맞는 것만 이어 붙이는 방식이었다.
Table of contents
Open Table of contents
첫 글자에서만 틀린 결과
대체로 잘 나왔는데 결과를 검수하다가 몇 건이 이상했다. 이상한 건들을 모아 보니 공통점이 있었고 전부 첫 글자에서만 어긋났다.
특정 위치에서만 틀린다는 것은 그 위치를 특별하게 만드는 무언가가 있다는 뜻이다. 첫 글자는 앞에 아무것도 없다는 점이 다른 위치와 달랐다.
조건부 갱신과 직전 값
함수 안을 보니 각 글자의 종류를 담는 변수가 있었는데 그것을 조건에 맞을 때만 갱신하고 있었다. 조건에 안 맞으면 값을 안 넣으니 이전 반복의 값이 그대로 남는다.
반복문 안에서 선언했다고 매 반복마다 초기화되는 것이 아니었다. 갱신하지 않으면 지워지는 것이 아니라 직전 값을 물려받는다.
값 없음을 명시적으로 넣는다
고치는 방법으로 조건을 옮기는 것을 먼저 생각했는데 그러면 다른 자리에서 같은 문제가 난다. 근본은 조건에 안 맞을 때 값을 안 넣는다는 점이었다.
그래서 조건에 안 맞으면 값 없음이 명시적으로 들어가도록 손봤다. 그러면 직전 값이 남을 자리가 없어지고 문제가 위치와 무관해진다.
경계에서만 틀리는 결함
이런 결함은 첫 번째나 마지막에서만 드러나므로 대부분의 입력에서는 안 보인다. 그래서 오래 살아남고 검수하다가 우연히 걸린다.
이후로 반복문을 볼 때 그 안의 변수가 매번 초기화되는지를 확인하게 됐다. 조건부로만 갱신되는 변수가 보이면 그 자리는 한 번 더 본다.
같은 함수에서 더 보인 것들
같은 함수를 읽다가 다른 것도 몇 개 보였는데 인자만으로 결과가 정해지는데도 휘발성 선언이 붙어 있었다. 그러면 필요 없는 재계산이 자주 일어난다.
참과 거짓의 내부 표현에 기대서 계산하는 자리도 있었는데 그것은 동작은 해도 의도를 가린다. 문자 코드 범위 같은 상수에는 왜 그 값인지를 주석으로 남겼다.
정리
- 반복 안에서 조건부로만 갱신하는 변수는 직전 값을 물려받는다
- 갱신하지 않는 것과 지워지는 것은 다르다
- 특정 위치에서만 틀리면 그 위치의 특수성을 본다
- 조건을 옮기는 대신 값 없음을 명시적으로 넣는다
- 경계에서만 틀리는 결함은 오래 산다
- 인자만으로 결과가 정해지는 함수에 휘발성 선언을 붙이지 않는다
- 내부 표현에 기댄 연산은 의도를 가린다
- 환경 종속 상수에는 왜 그 값인지 주석을 남긴다