While working on ideas for a new API for Puppet Functions and Orchestration I found myself wanting a couple of new types. Given a Puppet Labs Hack-Day, and some spare hours during the weekend I am now happy to present two additions to the type system:
Struct
- a hash with specified keys and type per keyTuple
- an array with specified sequence of types
These additional types will be available in the Puppet 3.5 release when using the --parser future option.
Struct Type
The Struct
type fully specifies the content of a Hash
. The type is parameterized
with a hash where the keys must be non empty strings, and the values must be types.
Here is an example, where the hash must contain the keys mode
and path
, and
mode
must have a value that is one of the strings "read"
, "write"
, or "update"
, and
the key path
must have a String
value that is at least 1 character in length.
Struct[{mode=>Enum[read, write, update], path=>String[1]}]
A Struct type is compatible with a Hash type both ways, given that the constraints they
express are met. A Struct
is a Collection
(just like Hash
), but its size is controlled
by the specified named entries.
Struct
supports optional values - this means that a matching hash may either have undef bound
to a key, or that the key is missing. A hash that has keys not specified in the Struct
will
not match.
An unparameterized Struct
matches all structs and all hashes.
Tuple Type
The Tuple
type fully specifies the content of an Array
.
It is to Array
what Struct
is to Hash
, with entries identified by their
position instead of by name. There is also some flexibility allowed with a variable
number of optional and trailing entries.
Tuple[T1, T2] # A tuple of exactly T1 and T2
Tuple[T1, T2, 1] # A tuple with a variable number of T2 (>= 0)
Tuple[T1, T2, 1, 3] # A tuple with a variable number of T2 (0-3 inclusive)
Tuple[T1, 5, 5] # A tuple with exactly 5 T1
Tuple[T1, 5, 10] # A tuple 5 to 10 T1
Tuple[T1, T1, T2, 1, 3] # A tuple of one T1, two T1, or two T1 followed by T3
All entries in the Tuple
(except the optional size constraint min/max count) must be a type
and denotes that there must be an occurrence of this type at this position. The tuple
can be modified such that the min and max occurrences of the given types in the type
sequence can be specified. The specification is made with one or two integer values or
the keyword default
. The min/max works the same way as for an Integer
range.
This way, if optional entries are wanted in the tuple the min is set to a value lower than the number of
given types, and if the last type should repeat the max is given as a value higher than the number of given types.
As an example, a size constraint
entered as Tuple[T, 0, 1]
means T occurs 0 or 1 time. If the max is unspecified, it defaults to infinity
(which may also be spelled out with the keyword default
).
["a", 1] =~ Tuple[String, Integer] # true
["a", 1,2,3] =~ Tuple[String, Integer, 1] # true
["a", 1,2,3] =~ Tuple[String, Integer, 0] # true
["a", 1,2,3] =~ Tuple[String, Integer, 0,2] # false
["a", 1,2,3] =~ Tuple[String, Integer, 4] # true
["a", 1,2,3] =~ Tuple[String, Integer, 5] # false
The Tuple type
is a subtype of Collection. Its size is specified by the given sequence
and the size constraint (which defaults to exactly the given sequence).
Summary
In this post you have seen the two new very useful types Struct
, which fully
qualifies a Hash
, and Tuple
which fully qualifies an Array
.
You find the index page with all the posts in the series here
The text above has been updated with a change to the TupleType's size constraint. It was a bad idea to let the size constraint only apply to the last element as this made it impossible to make a entries of different type optional. The text above now reflects the functionality that will be released in 3.5.0.
ReplyDelete