qa: New()/Quad() 다중 인스턴스화 이름 정정 — 이전 커밋의 오역 정정
직전 커밋에서 New()를 전부 Quad()로 치환했던 게 사용자 의도를 잘못 읽은 것이었음 — 사용자가 직접 바로잡음. 실제 설계: Quad(require의 반환값)는 이미 만들어진 기본 싱글톤 인스턴스이고, 그 안의 New 필드를 명시적으로 호출해야만 별도의 새 Quad 네임스페이스가 생긴다. "그냥 Quad()를 부르면 매번 새 인스턴스"였다면, 컴포넌트를 여러 모듈로 쪼갠 앱에서 각자 인스턴스를 "얻는" 것 자체가 "새로 만들기"가 되어 서로 다른 인스턴스가 생기는 사고로 이어졌을 것. architecture.md/dispatch-core-plan.md/bind-system-plan.md/ module-lifecycle-plan.md의 New() 서술을 되돌리고, qa-request round1의 A-3 절에 후속 정정 문단을 추가했다. quad-doc-auditor로 두 라운드 감사해 새 발견 0건까지 수렴시켰다. Co-authored-by: qwreey <me@qwreey.moe>
This commit is contained in:
parent
a1f948ae34
commit
b419d8c5e5
5 changed files with 105 additions and 46 deletions
|
|
@ -98,15 +98,50 @@ quad는 이제 "스크립트"가 아니라 **라이브러리**다. DOMless Roblo
|
||||||
정확한 패키지 이름, 아래 "구현 착수" 절 참고) — base가 가상돔 없이도
|
정확한 패키지 이름, 아래 "구현 착수" 절 참고) — base가 가상돔 없이도
|
||||||
프로바이더 패턴으로 백엔드를 받는 인터페이스만 정의하고, 실제 Roblox 구현은
|
프로바이더 패턴으로 백엔드를 받는 인터페이스만 정의하고, 실제 Roblox 구현은
|
||||||
`quad-roblox`가 담당.
|
`quad-roblox`가 담당.
|
||||||
13. **모듈은 기본 싱글톤, `Quad()`는 나중에.** 한 Lua 스레드에서 Roblox/비-Roblox
|
13. **모듈은 기본 싱글톤, `New()`는 추가 인스턴스가 필요할 때만.**
|
||||||
프로바이더를 동시에 쓸 일이 거의 없을 거라 판단 — 필요해지면 그때 `Quad()`
|
**[재정정, 2026-08-19 — 이전 정정(`New()`→`Quad()` 전면 치환)이
|
||||||
추가(**[정정, 2026-08-18 `/code-review high`] 이름은 아래 배너대로
|
부정확했음, `/code-review high` 이후 사용자가 직접 바로잡음]** `New`와
|
||||||
`New()`가 아니라 `Quad()`가 확정 — 이 문장도 그 이름으로 통일**).
|
`Quad`가 이름이 다투는 게 아니다 — 이전 정정이 "미래 API 이름은
|
||||||
**메커니즘도 이미 정해짐(2026-08-08 두 번째 세션, 새 설계 아니라
|
`Quad()`"라고 단정하며 `New()`를 전부 `Quad()`로 바꿨던 게 틀렸다.
|
||||||
기존 패턴의 자연스러운 연장)**: v1처럼 `require`를 감싸 `Init(QuadId?)`로
|
사용자 원문: *"내가 말한건 Quad() 만 제공하면 항상 모든 Quad 요구처에서
|
||||||
격리 인스턴스를 만드는 방식은 안 씀 — 대신 지금 있는 "팩토리가
|
각각의 Quad() 를 수행해서 새로운 모듈 스코프가 나온다는게 문제였어.
|
||||||
`BaseModule`을 뮤테이션" 패턴(14번) 그대로, 매번 새 `BaseModule`
|
그래서 Quad 는 기본적으로 생성된걸 리턴하긴 하는데, Quad.New() 도
|
||||||
테이블을 만들어 팩토리로 채우는 것뿐. 상세 근거는
|
제공하는거 어떻냐는거였음, 즉 New() 는 존재하고 기본 리턴은 New() 해서
|
||||||
|
주는건데, 리턴 안에 New 필드가 있고 그 함수를 쓰면 하나의 새로운 Quad
|
||||||
|
네임스페이스가 만들어지는식. 안 그러면 모든 컴포넌트를 나눈 모델
|
||||||
|
등에서 Quad() 를 해서 새로운 모듈 스코프가 나와서, 래핑된 Quad() 를
|
||||||
|
수행하는 부분을 따로 작성해두어야한다던가 해질꺼임."*
|
||||||
|
- **`Quad`(`require`의 반환값, 호출 아님)는 이미 만들어진 기본
|
||||||
|
인스턴스 자체다** — 모듈 로드 시점에 그 모듈 자신이 내부적으로
|
||||||
|
`New()`를 한 번 불러 만든 결과를 그대로 top-level 반환값으로 내보냄.
|
||||||
|
그래서 평범한 소비자는 아무것도 호출할 필요 없이 `require(quad)`가
|
||||||
|
돌려준 걸 바로 `Quad.Dispatch`처럼 씀(지금 싱글톤 단계와 동일한
|
||||||
|
접근 방식 — 달라지는 게 없음).
|
||||||
|
- **`Quad.New()`가 명시적 opt-in으로 설계됨**(**구현은 아직 미착수** —
|
||||||
|
지금은 싱글톤 단계라 `New` 필드 자체가 아직 안 노출됨, 바로 아래
|
||||||
|
"M0 스캐폴딩에 주는 함의" 참고) — 다중 인스턴스화가 실제로 붙는
|
||||||
|
시점엔 반환된 기본 인스턴스 **안에** `New` 필드(함수)가 생기고,
|
||||||
|
이걸 실제로 호출하면 완전히 **별도의 새 Quad 네임스페이스**
|
||||||
|
(자기만의 Dispatch 레지스트리 등)가 나오는 모양으로 짠다. Roblox +
|
||||||
|
비-Roblox 프로바이더를 진짜로 동시에 써야 하는 드문 경우에만 이걸
|
||||||
|
쓰게 될 것.
|
||||||
|
- **왜 "그냥 `Quad()`를 부르면 새 인스턴스"로 안 하는가** — 컴포넌트를
|
||||||
|
여러 파일/모듈로 쪼갠 실제 앱에서는 각 파일이 독립적으로 "Quad
|
||||||
|
인스턴스 하나 줘"를 요청하게 되는데, 그 요청 방법 자체가 "새로
|
||||||
|
만들기"라면 **파일마다 서로 다른, 서로 공유 안 되는 인스턴스**를
|
||||||
|
만들게 되는 사고가 난다(Dispatch 레지스트리가 안 공유되는 등) —
|
||||||
|
그러면 앱 전체가 하나의 공유 부트스트랩을 따로 작성해서 그걸 통해서만
|
||||||
|
Quad를 얻도록 강제해야 함. `require`가 이미 인스턴스화된 기본값을
|
||||||
|
주면 이 위험 자체가 원천적으로 없음 — 새 인스턴스가 필요한 그 드문
|
||||||
|
경우만 명시적으로 `.New()`를 부르면 되므로 실수로 스코프가 갈라질
|
||||||
|
일이 없다.
|
||||||
|
한 Lua 스레드에서 Roblox/비-Roblox 프로바이더를 동시에 쓸 일이 거의
|
||||||
|
없을 거라 판단해 지금은 `New()` 없이 싱글톤만 두고, 필요해지면 그때
|
||||||
|
`New()`를 노출한다. **메커니즘도 이미 정해짐(2026-08-08 두 번째 세션,
|
||||||
|
새 설계 아니라 기존 패턴의 자연스러운 연장)**: v1처럼 `require`를 감싸
|
||||||
|
`Init(QuadId?)`로 격리 인스턴스를 만드는 방식은 안 씀 — 대신 지금 있는
|
||||||
|
"팩토리가 `BaseModule`을 뮤테이션" 패턴(14번) 그대로, 매번 새
|
||||||
|
`BaseModule` 테이블을 만들어 팩토리로 채우는 것뿐. 상세 근거는
|
||||||
`base/dispatch-core-plan.md`의 "Dispatch는 프리미티브가 아니다" 절.
|
`base/dispatch-core-plan.md`의 "Dispatch는 프리미티브가 아니다" 절.
|
||||||
**[정정, 2026-08-18 구현 전 QA]** 옛 서술은 그렇게만 하면 지금
|
**[정정, 2026-08-18 구현 전 QA]** 옛 서술은 그렇게만 하면 지금
|
||||||
module-level state로 사는 모든 것(`_initializedBy` 마커, Dispatch
|
module-level state로 사는 모든 것(`_initializedBy` 마커, Dispatch
|
||||||
|
|
@ -116,9 +151,10 @@ quad는 이제 "스크립트"가 아니라 **라이브러리**다. DOMless Roblo
|
||||||
require 를 감싸지는 않고 단순히 InitModule(module) 등을 받도록 각
|
require 를 감싸지는 않고 단순히 InitModule(module) 등을 받도록 각
|
||||||
코드들을 약간 고쳐서 이것을 해결함."* 즉 **코드 변경 없이 자동으로**
|
코드들을 약간 고쳐서 이것을 해결함."* 즉 **코드 변경 없이 자동으로**
|
||||||
되는 게 아니라, module-level state를 참조하는 코드들이 모듈 인스턴스를
|
되는 게 아니라, module-level state를 참조하는 코드들이 모듈 인스턴스를
|
||||||
인자로 받도록 **손을 대야** 한다. 미래 API 이름도 `New()`가 아니라
|
인자로 받도록 **손을 대야** 한다 — `New()`가 실제로 호출되면(위 opt-in
|
||||||
**`Quad()`**(`Quad()`를 부르면 새 quad 인스턴스가 나오는 식)이고,
|
경로) 그 순간 만들어지는 새 `BaseModule` 테이블에 대해 이 손질이 필요.
|
||||||
**지금은 단순 싱글톤이라 `Quad()` 없이 `Quad.Dispatch`로 바로 접근**한다.
|
**지금은 `New()` 자체가 노출 안 된 싱글톤 단계라 `Quad.Dispatch`로
|
||||||
|
바로 접근**한다.
|
||||||
- **M0 스캐폴딩에 주는 함의**: 레지스트리를 module-level upvalue로
|
- **M0 스캐폴딩에 주는 함의**: 레지스트리를 module-level upvalue로
|
||||||
직접 잡아두면 나중에 다중 인스턴스화할 때 전면 수정이 된다. 지금
|
직접 잡아두면 나중에 다중 인스턴스화할 때 전면 수정이 된다. 지금
|
||||||
싱글톤으로 가되, **그 참조 형태를 나중에 인자 하나 받는 걸로 바꾸기
|
싱글톤으로 가되, **그 참조 형태를 나중에 인자 하나 받는 걸로 바꾸기
|
||||||
|
|
|
||||||
|
|
@ -112,11 +112,13 @@ RobloxFactory(QuadBase)` 세 줄 정도로 직접 조립하면 됨(별도 번들
|
||||||
아니라 **같은 팩토리 재호출(무시) vs 다른 팩토리로 유일 슬롯 충돌(에러)이라는
|
아니라 **같은 팩토리 재호출(무시) vs 다른 팩토리로 유일 슬롯 충돌(에러)이라는
|
||||||
서로 다른 케이스를 각각 가리키고 있었음**. 구현은 모듈 테이블에 "누가
|
서로 다른 케이스를 각각 가리키고 있었음**. 구현은 모듈 테이블에 "누가
|
||||||
초기화했는지" 마커(`_initializedBy = "roblox"`류, 정확한 이름은 구현 단계)만
|
초기화했는지" 마커(`_initializedBy = "roblox"`류, 정확한 이름은 구현 단계)만
|
||||||
두면 됨. 모듈 스코핑(`Quad()`, `base/architecture.md` 13번)과의 관계도
|
두면 됨. 모듈 스코핑(`New()`, `base/architecture.md` 13번)과의 관계도
|
||||||
실은 열려있던 게 아니라 자연히 풀림 — `Quad()`가 생기면 각 인스턴스가
|
실은 열려있던 게 아니라 자연히 풀림 — `New()`가 실제로 호출되면 그
|
||||||
별도 테이블이 되므로 이 마커도 테이블별로 독립적으로 스코핑됨(**[한정,
|
호출이 만드는 인스턴스가 별도 테이블이 되므로 이 마커도 테이블별로
|
||||||
2026-08-18 `/code-review high` — `architecture.md` 13번의 정정과 맞춤]**
|
독립적으로 스코핑됨(**[재정정, 2026-08-19 — `architecture.md` 13번의
|
||||||
단 "자동으로"는 아님 — module-level state를 참조하는 코드들이 모듈
|
재정정과 맞춤]** `Quad`는 이미 만들어진 기본 인스턴스이고 `New()`는 그
|
||||||
|
안의 opt-in 필드다, "`Quad()`를 부르면 매번 새 인스턴스"가 아님. 단
|
||||||
|
"자동으로"는 아님 — module-level state를 참조하는 코드들이 모듈
|
||||||
인스턴스를 인자로 받도록 손을 봐야 하는 건 architecture.md 13번의 정정
|
인스턴스를 인자로 받도록 손을 봐야 하는 건 architecture.md 13번의 정정
|
||||||
그대로, 여기서 반복 안 함).
|
그대로, 여기서 반복 안 함).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -150,7 +150,7 @@ src/schema/union.luau:48-68`) — 에러 메시지는 즉시 문자열로 만들
|
||||||
debug 모드일 때만. (Quad.debug: boolean = default false) 식이고, true 로
|
debug 모드일 때만. (Quad.debug: boolean = default false) 식이고, true 로
|
||||||
하면 디버깅 가능"*). `Quad.debug`는 **새 공개 API 표면**이라
|
하면 디버깅 가능"*). `Quad.debug`는 **새 공개 API 표면**이라
|
||||||
`base/module-lifecycle-plan.md`(모듈 표면)에도 반영이 필요하고,
|
`base/module-lifecycle-plan.md`(모듈 표면)에도 반영이 필요하고,
|
||||||
다중 인스턴스화(`Quad()`, `base/architecture.md` "확정된 결정" 13번) 시
|
다중 인스턴스화(`New()`, `base/architecture.md` "확정된 결정" 13번) 시
|
||||||
이 플래그가 인스턴스별인지 전역인지는 그때 같이 정한다.
|
이 플래그가 인스턴스별인지 전역인지는 그때 같이 정한다.
|
||||||
`Dispatch.listHandlers()`도 같은 디버그 표면에 속하는지(=플래그와 무관하게
|
`Dispatch.listHandlers()`도 같은 디버그 표면에 속하는지(=플래그와 무관하게
|
||||||
항상 호출 가능한지) 구현 시 정할 것.
|
항상 호출 가능한지) 구현 시 정할 것.
|
||||||
|
|
@ -599,28 +599,30 @@ end
|
||||||
전부 하나의 우선순위 스캔을 공유. **[정정, 2026-08-10 세션]** Tween은
|
전부 하나의 우선순위 스캔을 공유. **[정정, 2026-08-10 세션]** Tween은
|
||||||
더 이상 별도로 등록되는 핸들러가 아님 — Property 핸들러 내부에서
|
더 이상 별도로 등록되는 핸들러가 아님 — Property 핸들러 내부에서
|
||||||
소비되는 값-레벨 래퍼로 재설계됨(`base/tween-plan.md`).
|
소비되는 값-레벨 래퍼로 재설계됨(`base/tween-plan.md`).
|
||||||
- **모듈 재생성(`Quad()`)과의 관계 — 새 설계 불필요, 이미 있는 선례로 자연히
|
- **모듈 재생성(`New()`)과의 관계 — 새 설계 불필요, 이미 있는 선례로 자연히
|
||||||
풀림.**(**[정정, 2026-08-18 `/code-review high`] 헤딩이 옛 이름 `New()`를
|
풀림.** (**[재정정, 2026-08-19]** 이 헤딩을 한때 `Quad()`로 바꿨던 게
|
||||||
쓰고 있었음 — `architecture.md` 13번 항목과 같은 이유로 `Quad()`로
|
틀렸음 — `New()`가 맞는 이름, `architecture.md` "확정된 결정" 13번의
|
||||||
통일, 아래 "[한정]" 문단이 이미 정확한 이름을 씀**) v1처럼 `require`를
|
재정정이 소스. 요지: `Quad`(`require`의 반환값)는 이미 만들어진 기본
|
||||||
감싸 `Init(QuadId?)`로 격리 인스턴스를 만드는
|
인스턴스이고, 그 안의 `New` 필드를 명시적으로 호출해야만 별도의 새
|
||||||
|
Quad 네임스페이스가 생긴다 — "그냥 `Quad()`를 부르면 매번 새 인스턴스"가
|
||||||
|
아니다.) v1처럼 `require`를 감싸 `Init(QuadId?)`로 격리 인스턴스를 만드는
|
||||||
방식은 안 씀(위 "확정된 것" 절 — id 기반 조회 자체가 Ref로 대체되며
|
방식은 안 씀(위 "확정된 것" 절 — id 기반 조회 자체가 Ref로 대체되며
|
||||||
기각됨). 대신 이미 확정된 "base 유틸은 인터페이스, 실제 구현은 팩토리가
|
기각됨). 대신 이미 확정된 "base 유틸은 인터페이스, 실제 구현은 팩토리가
|
||||||
`BaseModule`을 뮤테이션해서 주입"(`RobloxFactory(BaseModule)`) 패턴을
|
`BaseModule`을 뮤테이션해서 주입"(`RobloxFactory(BaseModule)`) 패턴을
|
||||||
그대로 따름 — Dispatch의 handler 레지스트리도 `BaseModule` 테이블에
|
그대로 따름 — Dispatch의 handler 레지스트리도 `BaseModule` 테이블에
|
||||||
딸린 state 중 하나일 뿐이라, `_initializedBy` 마커에 대해 이미 확정된
|
딸린 state 중 하나일 뿐이라, `_initializedBy` 마커에 대해 이미 확정된
|
||||||
것과 완전히 같은 논리가 적용됨(위 "base 유틸은 인터페이스" 절, "`Quad()`가
|
것과 완전히 같은 논리가 적용됨(위 "base 유틸은 인터페이스" 절, "`New()`가
|
||||||
생기면 각 인스턴스가 별도 테이블이 되므로 이 마커도 테이블별로 독립적으로
|
실제로 호출되면 그 호출이 만드는 인스턴스가 별도 테이블이 되므로 이
|
||||||
스코핑됨" — 단 아래 "[한정]" 문단대로 코드 손질은 필요, 재설계까지는
|
마커도 테이블별로 독립적으로 스코핑됨" — 단 아래 "[한정]" 문단대로 코드
|
||||||
불필요). 다중 인스턴스화가 실제로 생기면 그 시점에
|
손질은 필요, 재설계까지는 불필요). 다중 인스턴스화가 실제로 생기면 그
|
||||||
BaseModule 전체를 인스턴스별 테이블로 만드는 메커니즘에 Dispatch도 자연히
|
시점에 BaseModule 전체를 인스턴스별 테이블로 만드는 메커니즘에 Dispatch도
|
||||||
같이 딸려가고, 호출부는 `module.Dispatch.process(...)`처럼 그 인스턴스
|
자연히 같이 딸려가고, 호출부는 `module.Dispatch.process(...)`처럼 그
|
||||||
테이블을 통해 접근하게 됨 — 지금 미리 프리미티브화해둘 이유가 없음.
|
인스턴스 테이블을 통해 접근하게 됨 — 지금 미리 프리미티브화해둘 이유가
|
||||||
**[한정, 2026-08-18 구현 전 QA]** 다만 "재설계 불필요"가 **"코드 변경
|
없음. **[한정, 2026-08-18 구현 전 QA]** 다만 "재설계 불필요"가 **"코드
|
||||||
불필요"는 아니다** — 사용자 판정에 따르면 그때는 module-level state를
|
변경 불필요"는 아니다** — 사용자 판정에 따르면 그때는 module-level
|
||||||
참조하는 코드들이 모듈 인스턴스를 인자로 받도록(`InitModule(module)` 류)
|
state를 참조하는 코드들이 모듈 인스턴스를 인자로 받도록
|
||||||
손을 봐야 하고, 미래 API 이름도 `New()`가 아니라 **`Quad()`**다
|
(`InitModule(module)` 류) 손을 봐야 한다(`base/architecture.md` "확정된
|
||||||
(`base/architecture.md` "확정된 결정" 13번). 지금은 싱글톤이라
|
결정" 13번). 지금은 `New()` 자체가 노출 안 된 싱글톤 단계라
|
||||||
`Quad.Dispatch`로 바로 접근한다.
|
`Quad.Dispatch`로 바로 접근한다.
|
||||||
|
|
||||||
### base가 소유하는 핸들러와 주입되는 엔진 op (2026-08-13 열네 번째 세션 신설)
|
### base가 소유하는 핸들러와 주입되는 엔진 op (2026-08-13 열네 번째 세션 신설)
|
||||||
|
|
@ -692,7 +694,7 @@ Fallback Handler들도 존재하지 않아**, 위 "매치 실패는 즉시 `erro
|
||||||
레지스트리**를 자기가 채우는 건 그 어느 쪽도 아니다 — 외부에 노출되는 init
|
레지스트리**를 자기가 채우는 건 그 어느 쪽도 아니다 — 외부에 노출되는 init
|
||||||
표면이 늘지 않고, 순서 의존도 없고(레지스트리와 등록 코드가 같은 모듈),
|
표면이 늘지 않고, 순서 의존도 없고(레지스트리와 등록 코드가 같은 모듈),
|
||||||
사용자가 할 일도 없다. 백엔드가 나중에 자기 Handler를 등록해 이기는 구조도
|
사용자가 할 일도 없다. 백엔드가 나중에 자기 Handler를 등록해 이기는 구조도
|
||||||
그대로다(Fallback 밴드는 항상 최하위). A-3의 다중 인스턴스화(`Quad()`)로
|
그대로다(Fallback 밴드는 항상 최하위). A-3의 다중 인스턴스화(`New()`)로
|
||||||
가더라도 자리는 그대로 — 그때는 "모듈 로드 시"가 "인스턴스 생성 시"가 될
|
가더라도 자리는 그대로 — 그때는 "모듈 로드 시"가 "인스턴스 생성 시"가 될
|
||||||
뿐이다.
|
뿐이다.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,9 +78,12 @@ init하려 하면 오류, 없는데 뭔가 생성해서 bind하려 해도 오류
|
||||||
|
|
||||||
한 Lua 스레드에서 둘 이상의 모듈 분화체(Roblox+비Roblox 동시)를 쓸 일이
|
한 Lua 스레드에서 둘 이상의 모듈 분화체(Roblox+비Roblox 동시)를 쓸 일이
|
||||||
거의 없을 거라 판단, 지금은 싱글톤으로 두고 필요해지면 다중 인스턴스화를
|
거의 없을 거라 판단, 지금은 싱글톤으로 두고 필요해지면 다중 인스턴스화를
|
||||||
추가. **[정정, 2026-08-18]** 그때의 API 이름은 `New()`가 아니라 `Quad()`이고,
|
추가. **[정정, 2026-08-18, 재정정 2026-08-19]** "코드 변경 없이 자동으로
|
||||||
"코드 변경 없이 자동으로 스코핑"되는 게 아니라 module-level state를 참조하는
|
스코핑"되는 게 아니라 module-level state를 참조하는 코드들이 모듈
|
||||||
코드들이 모듈 인스턴스를 인자로 받도록 손봐야 한다 —
|
인스턴스를 인자로 받도록 손봐야 한다. 이름은 `Quad()`가 아니라
|
||||||
|
**`New()`가 맞음**(2026-08-18에 한 차례 `Quad()`로 잘못 정정됐다가
|
||||||
|
바로잡힘) — `Quad`(`require`의 반환값)는 이미 만들어진 기본 인스턴스고,
|
||||||
|
`New()`는 그 안에서 명시적으로만 부르는 opt-in 필드다. 상세는
|
||||||
`base/architecture.md` "확정된 결정" 13번이 소스.
|
`base/architecture.md` "확정된 결정" 13번이 소스.
|
||||||
|
|
||||||
## 모듈 표면의 디버그 플래그 — `Quad.debug` (2026-08-18 신설, 사용자 요구)
|
## 모듈 표면의 디버그 플래그 — `Quad.debug` (2026-08-18 신설, 사용자 요구)
|
||||||
|
|
@ -174,13 +177,14 @@ print**(`base/dispatch-core-plan.md`의 "핸들러 계약" 절)이고, 앞으로
|
||||||
백엔드는 opt-in으로 `HANDLER_PRIORITY_FALLBACK + 1`짜리 가로채기
|
백엔드는 opt-in으로 `HANDLER_PRIORITY_FALLBACK + 1`짜리 가로채기
|
||||||
Handler를 추가로 등록할 수 있음 — 상세는
|
Handler를 추가로 등록할 수 있음 — 상세는
|
||||||
`base/dispatch-core-plan.md`의 같은 절. **중복 호출
|
`base/dispatch-core-plan.md`의 같은 절. **중복 호출
|
||||||
가드/`Quad()`와의 관계는 2026-08-04 3차 라운드에서 확정**: 같은 팩토리로
|
가드/`New()`와의 관계는 2026-08-04 3차 라운드에서 확정**: 같은 팩토리로
|
||||||
재호출하면 무시(no-op), 다른 팩토리로 재호출하면 에러(유일 슬롯 충돌 —
|
재호출하면 무시(no-op), 다른 팩토리로 재호출하면 에러(유일 슬롯 충돌 —
|
||||||
바로 위 "Bind는 누가, 어떻게 구현하는가" 절의 원칙과 일치) — `Quad()`가
|
바로 위 "Bind는 누가, 어떻게 구현하는가" 절의 원칙과 일치) — `New()`가
|
||||||
생기면 인스턴스별 테이블이 분리되므로 이 가드도 자연히 인스턴스별로
|
실제로 호출되면 그 인스턴스별 테이블이 분리되므로 이 가드도 자연히
|
||||||
스코핑됨(**[한정, 2026-08-18 `/code-review high`]** 위 "모듈 스코핑" 절의
|
인스턴스별로 스코핑됨(**[한정, 2026-08-18 `/code-review high`, 이름
|
||||||
정정과 맞춰 — "자동으로"는 아니고 module-level state를 참조하는 코드는
|
재정정 2026-08-19]** 위 "모듈 스코핑" 절의 정정과 맞춰 — "자동으로"는
|
||||||
손을 봐야 함, 그 손질까지 하고 나면 이 가드 자체는 재설계 불필요라는
|
아니고 module-level state를 참조하는 코드는 손을 봐야 함, 그 손질까지
|
||||||
뜻). **이 결론이 Dispatch의 handler 레지스트리에도
|
하고 나면 이 가드 자체는 재설계 불필요라는 뜻). **이 결론이 Dispatch의
|
||||||
|
handler 레지스트리에도
|
||||||
그대로 적용된다는 게 2026-08-08 두 번째 세션에서 재확인/일반화됨** —
|
그대로 적용된다는 게 2026-08-08 두 번째 세션에서 재확인/일반화됨** —
|
||||||
`base/dispatch-core-plan.md` "Dispatch는 프리미티브가 아니다" 절.
|
`base/dispatch-core-plan.md` "Dispatch는 프리미티브가 아니다" 절.
|
||||||
|
|
|
||||||
|
|
@ -100,6 +100,21 @@ D-7의 재역전 여부, N-4의 `NoneHandler`/`NilHandler` 역할 분담, ST-2
|
||||||
- **파급**: 실제 코드 배치에 영향 — module-level upvalue로 레지스트리를 잡아두면
|
- **파급**: 실제 코드 배치에 영향 — module-level upvalue로 레지스트리를 잡아두면
|
||||||
나중 다중 인스턴스화 때 전면 수정이 되므로, 지금부터 그 참조 형태를
|
나중 다중 인스턴스화 때 전면 수정이 되므로, 지금부터 그 참조 형태를
|
||||||
정해둘지 여부가 M0 스캐폴딩 결정이 됨.
|
정해둘지 여부가 M0 스캐폴딩 결정이 됨.
|
||||||
|
- **⚠️ [후속 정정, 2026-08-19] 위 "어긋나는 지점"의 이름 해석이 부정확했음
|
||||||
|
— `New()`를 통째로 `Quad()`로 바꾸는 건 사용자 의도가 아니었다.** 이
|
||||||
|
판정을 그대로 `base/architecture.md`에 반영했다가(2026-08-18) 여러 파일에
|
||||||
|
`New()`→`Quad()` 전면 치환이 퍼졌었는데, 사용자가 직접 바로잡음 —
|
||||||
|
*"New 와 Quad 가 이름 모순은 아닐꺼야... Quad 는 기본적으로 생성된걸
|
||||||
|
리턴하긴 하는데, Quad.New() 도 제공하는거 어떻냐는거였음, 즉 New() 는
|
||||||
|
존재하고 기본 리턴은 New() 해서 주는건데, 리턴 안에 New 필드가 있고
|
||||||
|
그 함수를 쓰면 하나의 새로운 Quad 네임스페이스가 만들어지는식."*
|
||||||
|
실제 의미: `Quad`(`require`의 반환값)는 이미 만들어진 기본 인스턴스이고,
|
||||||
|
`New()`는 그 안에 있는 **명시적 opt-in 필드**(호출하면 별도의 새
|
||||||
|
네임스페이스 생성) — "그냥 `Quad()`를 부르면 매번 새 인스턴스"가 아님.
|
||||||
|
컴포넌트를 여러 모듈로 쪼갠 앱에서 각자 `Quad()`를 불러 인스턴스를
|
||||||
|
"얻어야" 하는 모델이면 실수로 서로 다른 인스턴스가 생겨버리는 게
|
||||||
|
진짜 문제였음. 지금 유효한 서술은 `base/architecture.md` "확정된 결정"
|
||||||
|
13번의 재정정이 소스.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue