Reference and reshape other parts of the document
Pull other parts of the document in by reference, extend them, and relocate them with `move` and `copy`.
Rendered from
docs/how-to/reference-and-reshape.md
in the engine repository, where a correction belongs, and where the
test suite executes every example on this page.
A reference pulls another node in and unifies with it: it adds, it never overrides. That one sentence decides most of what follows:
base: { region:"us-east" tier:free }
prod: $.base & { replicas:3 }
{ "base": { "region": "us-east", "tier": "free" },
"prod": { "region": "us-east", "replicas": 3, "tier": "free" } }
prod extends the base and the base is untouched. (Note the quotes
on "us-east": a bare word stops at the -.) Now try to change a
field instead of adding one: the same base with prod: $.base & { tier: paid }, as tier.aon:
base: { region:"us-east" tier:free }
prod: $.base & { tier:paid }
$ aontu tier.aon
[aontu/scalar_value]: Cannot unify values at path $.prod.tier
...
Cannot unify value: "paid" with value: "free"
...
$ echo $?
1
A conflict, not an override. To let a referrer change a field, the base has to offer it as a default:
base: { region:"us-east" tier: *free|string }
prod: $.base & { tier:paid }
{ "base": { "region": "us-east", "tier": "free" },
"prod": { "region": "us-east", "tier": "paid" } }
The addressing and reshaping vocabulary, in full:
$.a.b: absolute path from the document root..a.b: path relative to the current map.key(): the key the current value is stored under.copy($.x): a deep copy,type/hidemarks cleared.move($.x): a reference that relocates: the source is dropped from the output, along with any unresolved optional keys.
The last one reshapes in the strict sense: the value leaves its old address:
m: { x?:number y:Y }
n: move($.m)
{ "n": { "y": "Y" } }
m is gone from the output and the unresolved optional x went
with it; a plain n: $.m would have kept both m and n.
Path grammar and composition rules are specified in References and
paths, and the
copy/move/key rows in
Functions. For reference
conjunction at scale, the feature-flag
catalog is the live version: its
served views are built as $.flags & $.envs.prod.flags & $.tenants.megacorp.flags, so every layer’s write flows into the
view by reference alone.