대조와 점검
10. Luban 대조 — 채택 · 변형 · 미채택 총괄
레이아웃 규칙의 상세는 레퍼런스에 있고, 여기는 판정만 적습니다.
10.1 구조
| Luban | 판정 | 이 설계 |
|---|---|---|
A1 ## 메타 셀이 시트 선별 | 변형 | 선언 셀 스캔. 시트 무시는 명시적 #와 recipe |
##var · ##type 등 헤더 행 | 채택 · 변형 | :field · :type — 행 키를 마커 열에 |
| 헤더 행 순서 자유 | 채택 | §3.3 |
##desc 계열 3순위 폴백 | 변형 | :desc 하나 |
##group 필드 그룹 (c,s) | 채택 | :target 행 — 같은 쉼표 목록 표기(§3.4). 이름 있는 그룹의 일반화는 보류 그대로 |
세로표(##column 전치) | 미채택 | 상수는 :const가, 단일 행은 §13의 예약이 자리입니다 |
병합 셀 · [이름…이름]으로 열 범위 | 미채택 | 경로 이름(reward.itemId)이 범위를 대신합니다. 병합 불필요 |
다단 ##var 재귀 헤더 | 미채택 | 경로 표기 한 행 |
10.2 필드와 값
| Luban | 판정 | 이 설계 |
|---|---|---|
*이름 멀티 로우 | 채택 · 변형 | 이름의 []. 경계 판정은 인덱스 신호로(§6.2) |
!이름 빈 칸 금지 | 다른 방식 | 옵셔널이 아닌 컬럼의 빈 칸 정책(OnBlankCell)이 이미 그 자리입니다 |
| 첫 필드 자동 non_empty | 다른 방식 | 기본 인덱스의 빈 칸 금지는 명시 규칙으로 이미 있습니다 |
| 이름 속성 5종 + 타입 속성(자리 이원화) | 변형 | 타입 칸 괄호 하나(§4.2) |
default= | 미채택 | 기본값은 시트가 아니라 DSL 4단계의 선언입니다(DSL §11.2) |
format=json/lua/lite 셀 표기 | 미채택 | (다) sep이 그 자리이고, 검증이 닿지 않는 자유 표기는 이 도구가 제거하려는 것입니다 |
| 스트림 모드(이름 없는 열 범위 순서 소비) | 미채택 | 성분 개수 정확 일치(합성 값 타입의 판정)만 받습니다. } 종료 토큰도 없습니다 |
열 한정 list(열 이름 0 1 …) | 변형 | [n] 원소 번호 — 이름이 아니라 경로 문법 |
| map 열 한정(컬럼 이름 = 키) | 미채택 | 매트릭스 표가 그 자리입니다 |
$type · $key · $value | 예약 | :type · :key · :value(§7) |
| enum 항목별 체크박스 열(flags) | 보류 | bitset과의 경계 결정이 선행입니다(§13) |
| alias(필드 · enum 항목) | 채택 | enum의 alias 컬럼(§8.4). 필드 alias는 담지 않습니다 — 이름이 둘이면 검색이 둘입니다 |
ref= path= range= set= size= index= validator | 있음 · 계승 | foreign · asset · min/max · allowed · size — 기능 대조 §4.5 |
10.3 선언과 운영
| Luban | 판정 | 이 설계 |
|---|---|---|
__tables__ 시트(mode · index · input) | 다른 방식 | 선언 셀 + recipe. 시트가 스키마라는 전제 유지 |
mode=one 단일 행 | 예약 | 기능 대조 §5.4의 도입 권고와 연결. 메타 키는 그 스펙에서 |
index=a+b 복합 키 | 채택 · 변형 | key="a,b"(§3.5). +를 들여오지 않습니다 |
index=a,b 독립 다중 키 | 채택 · 변형 | key의 세미콜론 목록 또는 *(§3.5) — SQL의 PRIMARY KEY + UNIQUE 체계 |
__beans__ · __enums__ | 다른 방식 | struct와 enum은 DSL이, 시트 enum은 :enum이 선언합니다 |
| define_from_file(시트가 스키마) | 이미 그렇습니다 | tabbit은 처음부터 시트가 스키마입니다 |
| A열 레코드 태그 + include/exclude | 채택 · 변형 | 마커 열의 낱말이 태그이고 레시피의 ExcludeTags가 부릅니다. 포함 목록은 들이지 않았습니다(태그) |
unchecked 태그 | 미채택 | 검사를 선별로 끄는 자리를 두지 않습니다 — 우회는 행 제외 |
sheet@file · 다중 파일 · 디렉터리 | 있음 | recipe의 소스 항목이 담당 |
variant(필드@변형 열, --variant) | 채택 · 변형 | :variant 행(§3.6). 이름 접미 @변형은 @N 와이어 태그와 충돌해 들여오지 않습니다. 행 세트와는 단위가 다릅니다 — §3.6의 대비표 |
11. 취약 사례 점검표 — 같은 사례에서 이 레이아웃의 동작
목적은 Luban의 지적이 아니라 참고입니다 — 실사용에서 관찰된 취약 사례를 수집했으니, 같은 사례를 이 레이아웃에 하나씩 넣어 보고 결함 없이 동작하는지를 설계 시점에 확인합니다. 각 행이 구현 시 테스트 픽스처 하나가 됩니다.
| # | 사례 (Luban에서의 결과) | 이 레이아웃의 동작 |
|---|---|---|
| 1 | 헤더 태그 오타 ##vra — 오류 로그만 남고 진행 | 마커 열의 미지 키는 오류(§3.1). 메타 괄호의 미지 키도 오류(§3.4 · §4.2) |
| 2 | 빈 셀의 뜻이 읽기 모드에 따라 다름 — 열 한정은 기본값, 스트림은 건너뜀(필드 밀림) | 빈 칸 정책은 하나이고 레이아웃 무관. 스트림 모드 자체가 없습니다 |
| 3 | 연장 행에 스칼라 값을 적음 — 새 레코드로 읽혀 「키 누락」으로 보고(실수와 메시지가 어긋남) | 규칙 3이 그 셀을 가리켜 「이 값은 레코드의 첫 행에」라고 보고(§6.2) |
| 4 | 연장하려던 행의 인덱스에 값을 적음 — 조용히 새 레코드 | 새 레코드가 되지만 스칼라 칸이 비어 있으므로 기본 정책 OnBlankCell: Error가 검출(§6.2) |
| 5 | 열 한정 list의 중간 원소를 비움 — 원소가 앞으로 당겨짐(문서가 함정으로 명시) | [n] 칸의 가운데 빈칸은 기본 거부(AllowArrayGaps) |
| 6 | A1 셀이 ##이 아니면 시트 통째 무시 — 조용한 소실 | 무시는 명시적 # 접두뿐이고, IncludeSheets에 적힌 것이 없으면 오류(기존) |
| 7 | 주석 열(# · 빈 이름)에 데이터가 차 있어도 조용히 버려짐 | 메모 공간은 명시적 # 표시입니다(§3.3). 표시도 이름도 없는 컬럼에 데이터가 있으면 오류 — 조용히 버려지는 경로가 없습니다 |
| 8 | 같은 속성을 적는 자리가 둘(##var 5종 vs ##type) — 자리를 틀리면 예외 메시지로 안내 | 자리가 하나(타입 칸 괄호)이므로 질문 자체가 없습니다 |
| 9 | 다단 헤더가 병합 셀에 의존 — 병합이 풀리면 구조가 바뀌고, 원소 순서가 흐트러지는 결함 주석이 소스에 남아 있음 | 병합을 읽지 않습니다. 구조는 경로 이름에 있고, 정렬해도 유지됩니다 |
| 10 | 시트 전체 정렬로 헤더가 데이터에 혼입 | 마커 열이 흐트러지므로 「데이터 행 위치에 :field」를 지목하는 오류(행 키 레이아웃 §5의 검출 그대로) |
| 11 | 바이너리 산출이 위치 기반 — 컬럼을 지우면 배포된 리더가 어긋남 | @N 와이어 태그(기존) |
| 12 | 완전 빈 행이 경계가 아님 — 표가 시트 끝까지 이어지고, 빈 행 수백 개는 성능 경고만 | 빈 행이 엔티티를 닫습니다(§3.2). 표 아래 메모가 표에 편입되는 사고도 함께 사라집니다 |
| 13 | 중복 키가 사전 삽입 예외로 보고 — 위치 없는 메시지 | 인덱스 유일성은 셀 위치와 함께 보고(기존 ValidateModel) |
| 14 | & 구식 구분자 · table= 폐기 문법의 흔적이 오류 메시지에 잔존 | 물려받을 이력이 없습니다. 다만 §12의 이관 안내(옛 표기 → 새 표기)는 같은 종류의 배려입니다 |
| 15 | 다형 리스트의 변종별 빈 컬럼이 「의도된 빈 칸」과 구분되지 않음 | 다형은 와이어 설계와 함께 확정(§7). 이 문제가 그 스펙의 입력입니다 |
12. 시트 작성자가 헷갈릴 수 있는 지점
설계 안에서 논리적으로는 정합하지만 처음 보는 사람이 걸릴 것으로 예상되는 자리입니다. 작성 문서에 눈에 띄게 적어야 하고, 오류 메시지가 이 표의 오른쪽을 안내해야 합니다.
| # | 헷갈리는 것 | 안내 |
|---|---|---|
| 1 | []의 두 자리 — costs + int[] vs costs[] + int | 「이름의 []는 행, 타입의 []는 셀 안」 한 줄. §5.1의 표를 작성 문서에 그대로 |
| 2 | :type이 두 곳에$type이 되어 행 키와 낱말이 갈립니다(§2). 이 항목이 $ 도입의 근거 하나였습니다 | |
| 3 | 원소 번호가 0부터 — 엑셀 행 번호는 1부터, 기존 Slot1도 1부터 | [1]로 시작하면 「[0]이 없습니다」로 지목. 옛 습관이 표기 오류로 조용히 살아남지 않습니다 |
| 4 | 인덱스 빈 칸의 뜻이 테이블에 따라 다름 — 멀티 로우 없는 표에서는 오류, 있는 표에서는 연장 신호 | [] 컬럼의 존재가 갈림길임을 작성 문서에 명시. 오류 메시지도 두 경우를 구분해야 합니다 |
| 5 | text(Common) 옛 습관 — 이 레이아웃에서는 미지 메타 키가 됨 | 오류 메시지가 (text=Common)을 직접 안내(§4.2) |
| 6 | 빈 행이 표를 끝냄 — Luban에서는 아니었음 | 여백은 마커 열 #나 메모 컬럼 구분선으로. §3.2 |
| 7 | *가 Luban의 멀티 로우 가 아니라 보조 인덱스 | [] 컬럼에 *가 붙으면 「멀티 로우는 [], 인덱스는 배열 불가」 두 가지를 함께 안내(§2) |
| 8 | (나)에서 타입 칸을 비우는 것 — 「타입을 안 적었는데 왜 되지?」 | 첫 멤버 컬럼의 struct 이름이 정본이라는 규칙(§4.3). 반복 기재를 허용(일치 검사)하므로 적어도 틀리지 않습니다 |
| 9 | 멀티 로우 그룹 2개가 나란히 — 같은 행의 원소끼리 짝이 아님(§6.1 규칙 5) | 짝이 필요한 데이터는 한 struct의 멤버로 묶으라고 안내 |
| 10 | -(값 없음)와 빈 칸의 구분 — 기존 규칙이지만 새 문서로 유입되는 사용자에게는 처음 | 빈 칸과 없음을 작성 문서 앞부분에 |
| 11 | #의 세 자리 — 마커 열(행 제외) · :field 단독(메모 컬럼) · :field 이름 앞(Tombstone) | 뜻은 「모델에 넣지 않음」 하나이고, 위치가 대상(행 · 컬럼 · 필드)을 정합니다. 작성 문서에 한 표로 |
| 12 | Luban의 index=a,b는 독립 키 2개, 이 레이아웃의 key="a,b"는 복합 키 하나 | 독립 단일 키는 *, 키 여러 개는 세미콜론(§3.5). Luban에서 오는 사용자용 주의 |
| 13 | :variant(필드의 값 컬럼 여러 벌)와 행 세트(행 집합 여러 벌) | §3.6의 대비표를 작성 문서에. 「지역별」이라는 말이 양쪽 모두에 걸리므로 예시로 갈라야 합니다 |