C.W.K.
Stream
Lesson 04 of 04 · published

선택 바구니는 바이트를 안 옮겨

~11 min · selection-basket, references, no-bytes

Level 0Finder 에서 길 잃음
0 XP0/36 lessons0/12 achievements
0/100 XP to next level100 XP to go0% complete
"바구니는 쇼핑 리스트지 쇼핑 카트가 아냐. 계산할 때까지 아무것도 선반을 안 떠나."

이사꾼이 아니라 수집가

선택 바구니는 진짜 짜증을 풀어: 다른 폴더 다섯에서 파일을 모아서 한 그룹으로 어딘가에 복사하고 싶어. 순진하게 짓는 방법은 더할 때마다 그 파일들을 숨은 스테이징 폴더로 실제로 옮기는 거야. Waygate 는 거부해. 바구니는 순서 있는 위치 참조 더하기 표시 힌트를 저장해 — 그리고 항목 더하거나 빼는 건 파일시스템 효과가 0. 진짜 오퍼레이션을 제출할 때까지 파일은 절대 집을 안 떠나.

낡은 항목은 눈에 보이게 낡은 채 남아

바구니가 복사본이 아니라 참조를 쥐니까, 항목이 낡을 수 있어 — 그게 가리키는 파일이 바구니에 있는 동안 이름 바뀌거나, 옮겨지거나, 지워져. Waygate 는 그걸 안 숨겨. 낡거나 오프라인 항목은 눈에 보이게 낡은 채 남아; 조용히 동명 대체물로 풀릴 수 없고, 변형을 승인 못 해. 참조가 더 이상 살아있는 파일을 안 가리키는 걸 보고, 네가 뭘 할지 정해 — 정확히 Track 2 의 진실-아닌-투영 규율을, 바구니에 적용한 거야.

제출은 평범한 플랜을 지어

마침내 바구니를 목적지로 드래그하거나 복사/이동을 누르면, 마법 같은 건 없어: 바구니가 자기 참조로 평범한 불변 오퍼레이션 플랜을 짓고 하나의 엔진에 건네. 다른 어떤 오퍼레이션과도 똑같은 재검증, 똑같은 저널링, 똑같은 충돌 처리, 똑같은 항목별 증거. 바구니는 그냥 소스를 조립하는 더 나은 방법이야; 변형 자체는 네가 이미 아는 평범하고 안전한 경로야.

선택 바구니는 순서 있는 참조랑 표시 힌트를 저장하고; 바이트를 안 옮겨. 항목 더하거나 빼는 건 파일시스템 효과가 없고, 낡거나 오프라인 타깃은 눈에 보이게 낡은 채 남아 변형을 승인 못 하고, 제출은 하나의 엔진으로 평범한 불변 오퍼레이션 플랜을 지어.
트랙 클리어 — 충돌이랑 모으기가 안전해. 명시적 충돌 정책, 플랜 빌더로서의 배치 이름변경, 전부-아니면-전무 허구 없음, 그리고 바이트 없는 선택 바구니. 패턴을 봐: 이것들 하나하나가 똑같은 엔진이랑 똑같은 투영 규칙의 새 클라이언트지, 절대 그것들의 포크가 아냐 — 고정 표면에 대한 Track 1 의 약속, 지켜졌어. 다음: 왜 이 중 어느 것도 UI 를 얼리도록 허용되면 안 되는지.

Code

바구니는 참조를 쥐고; 제출이 그걸 플랜으로 바꿈·swift
struct SelectionBasket {
    private(set) var entries: [LocationReference] = []   // ordered, no bytes

    mutating func add(_ ref: LocationReference) { entries.append(ref) }   // no FS effect
    mutating func remove(at i: Int) { entries.remove(at: i) }             // no FS effect

    // Each entry revalidates on display; stale ones show offline, don't act:
    func liveness() -> [ReferenceState] { entries.map { $0.revalidateForDisplay() } }
}

func submit(_ basket: SelectionBasket, to dest: LocationReference, kind: OperationKind) async {
    let plan = OperationPlan(kind: kind, sources: basket.entries,
                             destination: dest, collision: .ask,
                             expected: basket.entries.map(\.identityHint))
    await engine.submit(plan)   // ordinary immutable plan, ordinary engine
}

External links

Exercise

선택 바구니 두 설계를 비교해: (A) 더할 때마다 파일을 숨은 스테이징 폴더로 옮김; (B) 참조를 저장하고 제출까지 아무것도 안 옮김. 사용자가 파일을 더하고, 앱을 종료하고, 돌아올 때 — 또는 파일을 더하고 Finder 에서 지울 때 — 설계 A 에서 뭐가 깨지는지 나열해봐. 왜 참조 설계가 정직하게 남는 유일한 거야?
Hint
설계 A 는 바구니에 더하기만 해도 이미 파일시스템을 변형했어 — 이제 파일이 원래 폴더에서 '사라졌고', 세션 도중 종료가 파일을 숨은 폴더에 좌초시키고, 사용자의 멘탈 모델('난 리스트에 넣기만 했어')이 깨져. 설계 B 는 아무것도 안 만졌어: Finder 에서 지운 파일은 그냥 낡은 바구니 항목으로 보여. 참조 설계만 '바구니에 더하기' 를 부작용 없이 지켜.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.