오픈데이 Openday TIL 7
날짜를 20270830처럼 이어서 칠 수 있게 만들었다. 원래는 202708-30이 됐는데, 왜 하필 그렇게 어긋나는지를 알고 나니 그다음 판단이 다 따라 나왔다.
이어 치는 게 되는 건 칸이 「몇 자리인가」를 알기 때문이다
브라우저에는 날짜를 받는 칸이 기본으로 들어 있다. 우리가 만든 게 아니라 브라우저가 안까지 다 만들어 통째로 내주는 것이고, 이 글에서 「완제품 칸」이라고 부르는 게 그거다. 파일 고르기 창이나 색 고르기도 같은 종류다.
이 칸은 하나처럼 보이지만 안에 연·월·일 세 칸이 따로 있다. 숫자를 치면 한 칸을 채우고 다음 칸으로 넘어간다. 이 「넘어감」이 이어치기의 전부다.
넘어갈지 판단하려면 그 칸이 찼는지 알아야 하고, 찼는지 알려면 몇 자리짜리인지가 정해져 있어야 한다. 월은 두 자리, 일도 두 자리다. 그래서 08을 치면 바로 넘어간다.
연도만 그렇지 않다. 브라우저가 다루는 연도 상한이 275760년이라 이 칸은 여섯 자리까지 받는다. 네 자리를 쳐도 아직 안 찼으니 안 넘어간다.
20270830 을 이어 치면
연도 ← 202708 여섯 자리를 다 받는다
월 ← 30 12를 넘으니 접힌다
일 ← 빈다
사람은 「연월일 여덟 자리」로 세는데 칸은 「연도 여섯 자리까지」로 센다. 어긋나는 지점은 여기 하나다.
- 자동으로 넘어가는 칸은 「몇 자리인가」가 정해져 있어야 성립한다. 범위가 열려 있는 값에는 그 수가 없다
- 그리고 한 칸에서만 어긋나도 그 뒤가 전부 밀린다. 이어치기는 칸 하나하나가 아니라 칸들 사이의 약속 위에 서 있고, 약속은 한 군데만 깨져도 약속이 아니게 된다
- 카드번호·전화번호·인증번호처럼 자동으로 넘어가는 칸이 있는 곳은 전부 같은 구조다. 자리 수가 고정인 동안에만 매끄럽다
연도 칸만 네 자리에서 넘어가게 할 방법이 없었다
고치려면 「연도가 네 자리 차면 월 칸으로 넘겨라」를 어딘가에 적어야 한다. 그 자리가 없었다.
이 날짜 칸에 우리 코드가 할 수 있는 일은 이게 전부다.
- 완성된 날짜를 통째로 넣는다 —
2027-08-30 - 완성된 날짜를 통째로 읽는다
- 고를 수 있는 날의 최소·최대를 정한다
없는 것은 이쪽이다.
- 지금 커서가 세 칸 중 어디에 있는지 알기
- 「이제 다음 칸으로 넘어가라」고 시키기
- 연도 칸은 네 자리만 받게 정하기
- 연도 칸에만
2027을 넣기 — 값은 세 칸이 다 찬 상태로만 들어간다
키 입력을 가로채는 길도 막혀 있다. 키를 막는 것까지는 되는데, 막고 나면 대신 넣어 줄 방법이 없다. 넣는 수단이 「완성된 날짜 하나」뿐이라, 사람이 2027까지만 친 도중 상태를 표현할 수가 없다.
- 완제품이 편한 건 안쪽을 안 봐도 되기 때문인데, 안쪽이 틀렸을 때 못 들어가는 것도 같은 이유다. 편의와 막힘이 같은 성질에서 나온다
- 그래서 이 결정은 「더 낫게 만들자」가 아니라 「여기서는 고칠 수가 없다」에서 나왔다. 이 둘은 무게가 다르다 — 앞엣것은 미룰 수 있고 뒤엣것은 그 칸을 안 쓰는 것 말고 길이 없다
브라우저가 공짜로 주던 것을 버려도 되는 때
브라우저가 통째로 주는 것은 대개 직접 만든 것보다 낫다. 접근성, 휴대폰 자판, 나라마다 다른 날짜 표기, 손댈 일 없는 유지보수까지 딸려 온다. 그래서 「이건 직접 만들자」는 말이 나오면 일단 의심하는 게 맞다.
이번에는 버렸다. 셋을 따져서다.
- 못 고치는가 — 고칠 수 있으면 고치는 쪽이 훨씬 싸다
- 자주 쓰는가 — 어쩌다 걸리는 것이면 참는 쪽이 싸다
- 잃는 것을 되찾을 수 있는가 — 못 되찾으면 문제를 옮긴 것뿐이다
셋이 다 그렇다면 버려도 되고, 하나라도 아니면 다시 생각해야 한다. 앞 절이 첫째를 확인해 준 셈이고, 날짜는 이 앱에서 반복 일정을 만들 때마다 치는 것이라 둘째도 해당됐다.
못 되찾은 것을 적어 두는 것까지가 그 결정이다
버리기로 하면 딸려 오던 것을 하나씩 떠안는다. 되찾은 것과 못 되찾은 것이 갈렸다.
- 달력 — 되찾았다. 안 보이는 칸을 하나 두고 그 달력만 빌려 썼다
- 휴대폰 숫자 자판 — 되찾았다. 한 줄이면 된다
- 없는 날 거르기 — 되찾았다. 2월 30일 같은 건 짧은 검사로 걸러진다
- 나라별 표기 — 못 되찾았다. 지금 한국어만 쓴다는 사정에 기대 미뤘다
마지막 줄이 중요하다. 「지금은 상관없다」로 끝내면 나중에 언어를 붙일 때 이유를 모른 채 마주친다. 무엇을 포기했고 무엇에 기대어 포기했는지를 같이 적어 두면, 그 전제가 깨지는 날 여기부터 보게 된다.
넘치는 입력을 조용히 자르지 않는다
자리 수가 여덟으로 정해진 칸에 아홉 번째 숫자가 들어오면 무슨 일이 일어나야 하나. 답이 셋이다.
- 자른다 — 넘친 만큼 버린다
- 거절한다 — 아예 안 받는다
- 덮어쓴다 — 그 자리의 것을 바꾼다
셋 중 무엇인지 고르는 것이 설계다. 그리고 아무 말 없이 잘리게 두는 건 셋 다 아니다. 그건 고르지 않은 것이고, 고르지 않으면 「모양만 맞는 값이 조용히 만들어지는」 쪽으로 기운다.
이 칸은 덮어쓰기가 맞았다. 자리마다 뜻이 정해져 있어서(앞 넷은 연도, 다음 둘은 월) 하나를 끼워 넣는 순간 뒤가 통째로 밀려 뜻이 어긋난다.
조용한 손상은 오류보다 나쁘다
이 버그가 오래 안 보인 이유가 있다. 오류가 안 났다.
앞자리를 고쳤을 뿐인데 뒷자리가 바뀌는데도 화면에 아무 표시가 없다. 게다가 결과가 2202-70-83처럼 날짜 모양을 그대로 유지하고 있어서, 그럴듯한 만큼 더 안 보인다.
오류는 시끄러워서 고쳐진다. 조용한 손상은 사람이 눈으로 잡아내야 하고, 안 잡히면 그대로 저장된다. 이 앱에서는 그게 「반복 일정이 엉뚱한 해에 걸린다」가 된다.
같은 숫자를 다시 쳤더니 친 글자가 칸에 남았다
요즘 화면 코드의 기본 약속은 이렇다 — 값을 물려 주면 화면이 알아서 따라온다. 그래서 물려 준 값과 눈에 보이는 것이 늘 같다고 여기게 된다.
실제로는 물려 준 값이 바뀌었을 때 따라온다. 값이 그대로면 아무도 되돌려 놓지 않는다. 원래와 같은 숫자를 쳐서 결과가 안 바뀐 경우가 정확히 그 자리였고, 방금 친 글자가 칸에 남았다.
- 편하게 해 주는 장치일수록 조건을 모른 채 쓰게 된다. 잘 도니까 들여다볼 일이 없다
- 조건을 모르면 조건 밖에서 난 일을 버그로 못 알아본다. 「그럴 리가 없는데」에서 시간이 간다
- 그런 자리에서는 약속을 잠깐 벗어나야 한다. 규칙을 어기는 게 아니라 그 규칙이 안 닿는 자리를 메우는 것이다
가져온 코드는, 코드가 아니라 그것이 풀던 문제를 본다
달력을 여는 코드가 앱 안에 이미 있어서 그대로 가져왔다. 그런데 반대로 돌았다 — 날짜를 쳐 놓고 달력을 열면 그 날이 아니라 이번 달이 나왔다.
가져온 쪽은 「고르면 무언가 하는 자리」였다. 같은 날을 다시 골라도 동작해야 해서, 열기 전에 칸을 비워 두고 있었다. 새 자리는 「값을 정하는 자리」다. 같은 날을 고르면 아무 일도 안 일어나는 게 맞으니 비울 이유가 없었다.
- 가져올 때 봐야 하는 건 코드가 무엇을 하는지가 아니라 무엇을 막으려고 그렇게 돼 있는지다. 그다음 그게 여기서도 막을 것인지 묻는다
- 같은 앱 안에서 옮길 때가 오히려 위험하다. 남의 코드는 의심하고 보는데 우리 코드는 안 그런다. 같은 달력, 몇 줄 안 되는 코드였는데도 정반대였다
값이 싸면 고르게 하지 말고 둘 다 남긴다
칸을 직접 만들면서 달력을 없앨 수도 있었다. 날짜를 이어서 칠 수 있으면 달력이 굳이 필요하냐는 것이다.
그러지 않았다. 날짜를 아는 사람은 치는 게 빠르고, 「다음 주 금요일」처럼 요일로 세는 사람은 달력이 빠르다. 어느 한쪽이 맞는 게 아니라 사람마다 다르고, 같은 사람도 그때그때 다르다.
- 「둘 중 무엇이 나은가」를 묻기 전에 「둘 다 두는 값이 얼마인가」를 먼저 본다
- 여기서는 안 보이는 칸 하나와 버튼 하나였다. 그 정도면 고를 일이 아니다
- 값이 비쌀 때만 고르는 문제가 된다. 싼데도 고르려 드는 건 대개 취향 싸움이다
요약 — 만들어진 것을 쓸 때는 그것이 무엇에 기대는지까지 본다
여섯 가지가 다 한 줄기였다. 완제품 칸이 편했던 이유(안을 안 봐도 된다)가 그대로 못 고치는 이유였고, 버릴지 정하는 기준도 결국 딸려 오던 것을 되찾을 수 있느냐였다. 알아서 맞춰 주는 장치도, 앱 안에서 가져온 달력 코드도 같은 자리에서 걸렸다 — 잘 도는 동안에는 조건이 안 보이고, 조건 밖으로 나가는 날 처음 보인다.
- 만들어진 것을 쓸 때는 무엇을 해 주는지가 아니라 무엇에 기대어 그렇게 해 주는지를 본다
- 그 전제가 이 자리에서도 참인지 묻는다. 아니라면 고칠 수 있는 자리인지부터 확인하고, 못 고칠 때에만 직접 만드는 쪽으로 간다
- 무엇을 포기했고 무엇에 기대어 포기했는지는 적어 둔다. 전제가 깨지는 날 여기부터 보게 된다