Cocos2d-x 클라이언트에서 아이템 획득 확률을 확인하려고 .cpp 를 봤다. 주석은 5% 라고 하고 코드는 12% 였다.
// 희귀 아이템은 5% 확률로 나온다
if (rand() % 100 < 12) { ... }
Table of contents
Open Table of contents
주석과 코드가 달랐다
svn blame 으로 그 줄을 뒤져 보니 확률을 두 번 올린 적이 있었다. 주석은 처음 그대로였다.
이 상태에서 코드를 읽으면 주석이 낡았다고 보거나 코드가 잘못됐다고 보거나 둘 중 하나다. 어느 쪽인지 코드만 봐서는 모른다. 확인하려면 svn log 를 뒤져야 하고 그것도 커밋 메시지가 남아 있어야 한다. 주석 한 줄이 확인 비용을 만든다.
낡는 주석과 안 낡는 주석
Classes 아래 주석을 종류별로 나눠 봤다. 값을 다시 적은 것과 왜 그런지 적은 것과 무엇을 조심해야 하는지 적은 것 셋이다.
값을 다시 적은 것은 값이 바뀌면 바로 거짓이 된다. 그나마 .cpp 를 보면 알 수 있는 내용이다. 왜 그런지 적은 것은 값이 바뀌어도 유효하다. 조심할 것을 적은 것은 값과 무관하다. 낡는 것은 첫 번째뿐이었다.
값 대신 이름을 붙였다
값을 주석에 옮겨 적는 대신 const 로 뺐다.
const int RARE_ITEM_RATE = 12; // 초반 이탈률 대응으로 상향 중
값이 BalanceConst.h 한 곳에 있고 그 옆에 왜가 적혀 있다. 값을 바꾸러 가면 주석도 같은 자리에서 보이므로 둘이 어긋나기 어렵다.
의심스러운 주석도 grep 으로 훑었다. 숫자가 든 주석 14 군데 중 절반쯤이 코드와 안 맞았다. 날짜가 든 주석은 23 군데였고 대부분 변경 이력이었다.
TODO 와 FIXME 도 세어 봤다.
$ grep -rn "TODO\|FIXME" --include=*.cpp --include=*.h Classes/ | wc -l
41
41 개인데 누가 언제 적은 것인지가 없다. svn blame 을 걸어 보니 절반이 1 년 넘은 것이었다. 남길 것은 이름과 날짜를 같이 적게 했다.
확률을 뽑는 자리도 같이 봤다. rand() % 100 을 쓰고 있었는데 ccMacros.h 에 CCRANDOM_0_1() 이 있다. srand 를 AppDelegate 에서 한 번 부르는 것도 그때 확인했다. 안 부르면 매번 같은 순서가 나온다.
이력을 코드에서 뺐다
GameConfig.h 위쪽의 이력 주석은 이런 모양이었다.
// 2011-11-03 확률 5 → 8 (기획 요청)
// 2011-12-20 확률 8 → 12 (재조정)
SVN 이 이미 하고 있는 일이다. 코드에 쓰면 같은 내용이 두 곳에 생기고 하나가 낡으며 파일이 계속 길어진다. 지우면서 그 내용을 커밋 메시지로 옮겼다.
코드를 읽으면 그대로 아는 주석도 지웠다. i++ 위에 「i 를 하나 늘린다」가 붙어 있는 식이다. 아무것도 안 알려 주면서 읽을 것만 늘린다. 주석이 있어야 하는 자리는 코드만 봐서는 왜인지 모르는 곳이었다.
// 이 순서로 해제해야 한다. 반대로 하면 텍스처 참조가 남는다
sprite->removeFromParentAndCleanup(true);
texture->release();
고치는 습관도 잡았다. .cpp 를 고칠 때 그 위아래 주석을 같이 읽는다. 지금 코드를 설명하고 있지 않으면 고치거나 지운다. 읽는 데 몇 초인데 안 하면 다음 사람이 몇 분을 쓴다.
정리
- 값을 다시 적은 주석은 값이 바뀌면 거짓이 된다
- 어느 쪽이 맞는지 코드만 봐서는 모르고 확인에 시간이 든다
- 값 대신 이름을 붙이고 그 옆에 왜를 적는다
- 값과 주석이 같은 자리에 있으면 어긋나기 어렵다
- 변경 이력을 주석에 쓰지 않는다.
svn log가 이미 한다 - 숫자나 날짜가 든 주석은 낡았을 가능성이 크다
- 코드를 읽으면 아는 내용은 지운다
- 코드를 고칠 때 그 주변 주석을 같이 읽는다