From 54d933ecc2d255ac8f2eafb6728730051b2b518b Mon Sep 17 00:00:00 2001 From: Lilleman auf Larv Date: Mon, 28 Sep 2026 23:18:25 +0200 Subject: [PATCH] Name renderScope.groupHold for what it returns, correct pathDraw's pins comment, and drop the done round item --- docs/decisions.md | 2 +- drawfence_test.go | 6 +++--- hold.go | 2 +- holdset.go | 7 ++++--- path.go | 6 +++--- record.go | 4 ++-- render.go | 4 ++-- todo.md | 3 --- 8 files changed, 16 insertions(+), 18 deletions(-) diff --git a/docs/decisions.md b/docs/decisions.md index 0d4dc26..f0a3be8 100644 --- a/docs/decisions.md +++ b/docs/decisions.md @@ -312,7 +312,7 @@ file the stem of the units it holds. Two declarations of any kind — function, method, field, type — share a name only where one definition covers both: the same kind of value, counted or addressed the same way, so a reader landing on the wrong one concludes nothing false. `Fake` on each template kind -renders one value from what it is called on; `renderScope.hold` returns the `*hold` it +renders one value from what it is called on; `renderScope.groupHold` returns the `*groupHold` it names. A bare function never shares a name with a method: a search for the name returns both, and a call site shows no receiver to tell them apart. `TestNoFunctionSpellsAMethod` holds that, and review judges the rest. Serves goal 2: names that tell the truth, and reaching diff --git a/drawfence_test.go b/drawfence_test.go index 6475138..c426bc4 100644 --- a/drawfence_test.go +++ b/drawfence_test.go @@ -133,8 +133,8 @@ func renderRoot(s *session, t *template) { for r := 0; r < t.table.rowCount(); r++ { var set holdSet sc := renderScope{set: &set} - sc.hold().pins.pin(t.table, r) - render(s, t.table.pinnedRow, sc.at(t.table.pinnedRow, &sc.hold().pins)) + sc.groupHold().pins.pin(t.table, r) + render(s, t.table.pinnedRow, sc.at(t.table.pinnedRow, &sc.groupHold().pins)) } case t.repeat > 1: expand(s, t, sc) @@ -147,7 +147,7 @@ func renderRecordRoot(s *session, t *template, columns []Column) { var set holdSet sc := renderScope{set: &set} if t.table != nil { - t.table.drawIn(s, &sc.hold().pins) + t.table.drawIn(s, &sc.groupHold().pins) } renderRecord(s, t, columns, sc) } diff --git a/hold.go b/hold.go index 8b507fb..02ff5d5 100644 --- a/hold.go +++ b/hold.go @@ -45,7 +45,7 @@ func readField(s *session, t *template, held *hold, sc renderScope, a arm) readV } w := pathDraw{s: s, held: held, a: &a} if isRef(a.key) && len(a.tail) > 0 { - group := sc.hold() + group := sc.groupHold() w.held, w.pins = &group.hold, &group.pins } if r, done := w.held.value[a.path]; done { diff --git a/holdset.go b/holdset.go index c798226..eacf77f 100644 --- a/holdset.go +++ b/holdset.go @@ -12,8 +12,9 @@ type holdSet struct { } // renderScope is where a render reads its reference paths: a hold set, in the draw group of the -// template rendering; and row, the row of the table rendering, which its columns read. It passes by value, and what is read from it reaches a map key, an interface or -// a func value only as a copy; else sc, and with it every render's hold set, moves to the heap. +// template rendering; and row, the row of the table rendering, which its columns read. It passes +// by value, and what is read from it reaches a map key, an interface or a func value only as a +// copy; else sc, and with it every render's hold set, moves to the heap. type renderScope struct { set *holdSet group string @@ -67,7 +68,7 @@ func (sc renderScope) rowOf(t *table) int { return sc.row.row } -func (sc renderScope) hold() *groupHold { +func (sc renderScope) groupHold() *groupHold { if sc.group == "" { return &sc.set.unnamed } diff --git a/path.go b/path.go index 139fe2f..29574ed 100644 --- a/path.go +++ b/path.go @@ -332,9 +332,9 @@ func (w *pathProbe) readRow(t *table, r tableRoute) error { return nil } -// pathDraw draws the rows and variants a proved path reads, pinning the rows in pins, which -// only a path from a reference needs: a table is a category. For a held read, held keeps the -// variant drawn at each level of a, so paths sharing a prefix share it. +// pathDraw draws the rows and variants a proved path reads, pinning the rows in pins; pins is nil +// for a sibling path, which never crosses a table, since a table is only a category. For a held +// read, held keeps the variant drawn at each level of a, so paths sharing a prefix share it. type pathDraw struct { s *session pins *pinSet diff --git a/record.go b/record.go index 4ca8d0c..d0b4a79 100644 --- a/record.go +++ b/record.go @@ -159,7 +159,7 @@ func tableRecord(s *session, t *table, tail []string, sc renderScope) (node, err } switch n := n.(type) { case *table: - n.drawIn(s, &sc.hold().pins) + n.drawIn(s, &sc.groupHold().pins) return n, nil case *tableRow: return n.t, nil @@ -264,7 +264,7 @@ func recordOf(n node) (*template, []Column, error) { func renderRecord(s *session, t *template, columns []Column, sc renderScope) *Record { sc = sc.in(t) if t.table != nil { - sc = sc.at(t.table.pinnedRow, &sc.hold().pins) + sc = sc.at(t.table.pinnedRow, &sc.groupHold().pins) } r := &Record{columns: append([]Column(nil), columns...)} for i := range r.columns { diff --git a/render.go b/render.go index 8e9a7c9..9bffb12 100644 --- a/render.go +++ b/render.go @@ -33,7 +33,7 @@ func (f *Generator) Fake(path string) (string, error) { if _, ok := n.(*folder); ok { return "", fmt.Errorf("fejkdata: %s names a folder, not a value", path) } - return render(f.rand, n, sc.at(n, &sc.hold().pins)), nil + return render(f.rand, n, sc.at(n, &sc.groupHold().pins)), nil } // descend walks a caller's path to the node it names, pinning in sc the rows it @@ -43,7 +43,7 @@ func descend(s *session, root node, segments []string, sc renderScope) (node, er if _, err := (&pathProbe{drawn: map[*table]bool{}}).walk(root, segments); err != nil { return nil, err } - return drawPath(root, segments, "", &pathDraw{s: s, pins: &sc.hold().pins}), nil + return drawPath(root, segments, "", &pathDraw{s: s, pins: &sc.groupHold().pins}), nil } // render evaluates a compiled node to a string. compile validates every node up diff --git a/todo.md b/todo.md index 37eb540..3420edc 100644 --- a/todo.md +++ b/todo.md @@ -23,9 +23,6 @@ Shape 5.8, Self-sufficiency 5.7), every seat capped by Locality, all nine naming This round, in order: -- Split `hold`'s two lifetimes, the expansion's sibling hold and the render's group - hold, into two types, and stop `readField` rewriting `sc.pins`: which pins a column - reads depends on which distant caller last overrode them, the cost seven seats named. - Return each phase's output from compile, link and format compile, not fill `template`'s 25 fields in place from four files: five seats had to know which phase a function runs in to know which fields are valid yet.