Using the -map option a schema can be specified that puts constraints on which branches are allowed, and what values are allowed in the branches. A schema is also organised as a map. when the first element in a value starts with an asterisk, it is an endnode. Otherwise it is the schema of the submap starting at the name of that value. An endnode consists of a type indicator (the first element starting with an asterisk) and type parameters. A number of types are available by default (*any, *int, *regexp, *date, *named *list, ...). New types can be added using either Tcl or C code.
If a schema contains names consisting of a list where element 0 is a questionmark these are treated specially: The list must have 2 further elements: element 1 is the long name for the value, and element 2 the short name. Both long and short name can be used to set or get values from the map. However, map_set will always return a struct with the short name (efficient storage), while map_get will return the long form.
set the value for tag % set list {a 1 b 4} a 1 b 4 % set list [map_set $list c 3] a 1 b 4 c 3 % map_set {a 1 b 4 c 3} b 2 a 1 b 2 c 3 example of nesting: % map_set {a 1 b {a 1 b 4} c 3} {b b} 2 a 1 b {a 1 b 2} c 3 example of map: % set struct { reg {*regexp {^a[0-9]} ?} sub { a {*any ?} b {*between 0 10 ?} } ints { *named {*int ?} } } % set data {} % set data [map_set -map $struct $data {sub b} 9] sub {b 9} % set data [map_set -map $struct $data {sub b} 11] error: 11 is not between 0 and 10 at field "b" at field "sub" % set data [map_set -map $struct $data ints {a 9}] sub {b 9} ints {a 9} % set data [map_set -map $struct $data {sub b} ?] ints {a 9}
% set struct { reg {*regexp {^a[0-9]} ?} sub { a {*any ?} b {*between 0 10 ?} } ints { *named {*int ?} } } % map_get -map $struct {ints {a 9}} {sub b} ? % map_get -map $struct {ints {a 9}} {ints} a 9
% map_unset {a 1 b 2} b a 1