TUI::Form
Macros
Block-DSL sugar over FieldSpec(M) construction. Must be called as a
bare top-level statement (not the right-hand side of an assignment)
— the macro itself emits both a helper class declaration and the
name = HelperClass.build assignment as two sibling top-level
statements, since Crystal disallows a macro emitting a class
declaration from expression/value position ("can't declare class
dynamically").
Every field call still ends up as a literal m.prop/m.prop = v
reference inside the generated self.build method — a property
name that doesn't exist on the model is an ordinary Crystal
"undefined method" compile error, not a silent no-op, PROVIDED the
constant this macro assigns is actually read somewhere (Crystal
skips type-checking of an unread top-level constant's initializer
entirely — this macro can't change that ordinary Crystal semantic,
so a TUI::Form.define block whose target constant is never
referenced elsewhere would not be type-checked; every real call
site passes the result straight into Form::Host, which reads it,
so this is a non-issue in practice, but it means a spec exercising
this safety guarantee must actually call .get/.set, not just
assert "it compiles").