콘텐츠로 이동

브랜드 술어

quad의 값 타입은 브랜드로 표시됩니다 — 생성 시점에 자기 브랜드(weak-key 집합)에 스스로 등록하고, is* 술어가 그 집합에 있는지 묻습니다. 구조(필드 모양)를 보지 않으므로 흉내낸 테이블은 통과하지 못하고, 역조회(값 → 브랜드 이름)는 없습니다.

이 페이지의 심볼: 술어 표 · 포함 관계 · 브랜드가 없는 값 · 사본 경계

-- 설치 경로는 프로젝트 구성에 따라 다르다(00-installation 참고)
local Quad = require(<quad-base 모듈 경로>)
local QuadRoblox = require(<quad-roblox 모듈 경로>).QuadRoblox
local q = Quad:UseProvider(QuadRoblox) -- quad-roblox 백엔드 설치: D/Tween/Animate/OnChange가 생긴다
local D = q.D

전부 (x: any) -> boolean 한 모양입니다(q.isInst만 파라미터 이름이 value). 부작용이 없고, 어떤 값을 줘도 던지지 않습니다 — 등록되지 않은 테이블·nil·숫자에는 그냥 false.

이름 참인 값 어디서
q.isEpoch(x) q.Source(v), q.Ref(v)/q.PreRef(v)/q.PostRef(v)Revision을 가진 값 quad-base 기본 표면
q.isSource(x) q.Source(v) quad-base 기본 표면
q.isState(x) q.Source(v), :Compute/:With가 만든 파생 State, :Gate가 끼운 게이트 노드 quad-base 기본 표면
q.isStore(x) q.Store(defaults?) quad-base 기본 표면
q.isObserver(x) state:Observer(fn)이 돌려준 핸들 quad-base 기본 표면
q.isEffect(x) q.Effect(fn, ...deps)가 돌려준 EffectHandle quad-base 기본 표면
q.isBlocker(x) q.Blocker() quad-base 기본 표면
q.isContext(x) q.Context() quad-base 기본 표면
q.isProvider(x) q.Context.Provider(name?) quad-base 기본 표면
q.isModifier(x) q.Modifier(...), D.Modifier.<Class>(...), Modifier.TypedFactory로 만든 생성자의 결과 — 타입드든 아니든 전부 quad-base 기본 표면
q.isRef(x) q.Ref(v), q.PreRef(v), q.PostRef(v) quad-base 기본 표면
q.isPreRef(x) q.PreRef(v) quad-base 기본 표면
q.isPostRef(x) q.PostRef(v) quad-base 기본 표면
q.isMapperDescriptor(x) D.Mapper.<Class>(key)(props), q.newMapperClass(name)(key)(props) quad-base 기본 표면
q.isSlot(x) q.Slot(initial?), 그리고 반응형 요소를 감싸며 내부적으로 만들어지는 래퍼 Slot quad-base 기본 표면
q.isTag(x) q.Tag(...), Tag.Merged(...), tag:Added(...)/:Removed(...)의 결과 quad-base 기본 표면
q.isAttr(x) q.Attr(...), q.StringAttr/q.NumberAttr/q.BooleanAttr가 만든 단일 항목 그룹 quad-base 기본 표면
q.isAttrKey(x) q.AttrKey(name), 그리고 Attr 그룹이 이름마다 내부로 쓰는 키 객체 quad-base 기본 표면
q.isInst(value) 백엔드가 “요소”로 인정하는 값 — quad-roblox면 실제 Instance 백엔드 주입 (미설치면 에러)
q.isTween(x) q.Tween{ ... } quad-roblox 확장

시그니처의 정본은 quad-types/src/init.luauQuad 레코드입니다. 한 묶음에 몰려 있지는 않습니다 — isEpoch부터 isMapperDescriptor까지는 브랜드 술어 묶음에, isSlotSlot 표면과 함께, isTag/isAttr/isAttrKey는 Tag/Attr 표면과 함께, isInst는 주입 슬롯 묶음에 선언돼 있습니다. isTweenquad-roblox/src/init.luauRobloxExtension에 있습니다 — 백엔드 값의 브랜드는 백엔드 표면이 싣습니다.

세 술어는 다른 술어의 상위 집합입니다. 값을 분기할 때 좁은 쪽을 먼저 물어야 합니다.

  • q.isState(x)q.isSource(x)를 포함합니다 — Source는 구조적으로 State입니다.
  • q.isRef(x)q.isPreRef(x)q.isPostRef(x)를 포함합니다 — 셋은 같은 런타임을 쓰고 브랜드만 다릅니다. PreRefPostRef는 서로 배타입니다.
  • q.isEpoch(x)는 가장 넓습니다 — Source와 세 종류의 Ref가 전부 참입니다.

한 값이 여러 브랜드를 동시에 가질 수 있다는 뜻이기도 합니다. q.PreRef(nil) 하나에 대해 isEpoch/isRef/isPreRef가 전부 참입니다.

  • 센티널q.None/q.Detach/q.KeyGone/q.MapperRoot에는 브랜드가 없고 술어도 없습니다. 판정은 언제나 신원 비교입니다: v == q.None. (isNone이라는 함수는 없습니다.)
  • q.Relate()가 돌려주는 릴레이션, q.Void 같은 잎 유틸도 브랜드 대상이 아닙니다.
  • 프로바이더가 자기 값 타입을 추가할 때는 모듈 표면에 is<Brand> 필드를 얹는 것이 그 자체로 등록입니다 — 디스패치가 매치 실패 진단에서 값의 브랜드 이름을 찾을 때 그 규약대로 모듈을 훑습니다(quad-base/src/Dispatch/init.luau). q.isTween이 그 첫 사례입니다.

브랜드 집합은 quad-base 사본마다 따로 삽니다. 같은 프로젝트에 quad-base가 두 벌 설치돼 있으면 A 사본이 만든 Source는 B 사본의 q.isSource에서 false입니다 — 술어가 구조가 아니라 등록 여부를 보기 때문입니다. 같은 이유로 프로바이더 신원(q.Context.Provider)도 사본을 넘지 못합니다.

q.New()로 인스턴스를 여러 개 만드는 것은 여기 해당하지 않습니다 — 브랜드는 모듈 인스턴스가 아니라 파일(사본) 단위라, 한 사본에서 만든 인스턴스들은 서로의 값을 알아봅니다.