Skip to content

Commit 34ff616

Browse files
miharpclaude
andcommitted
Document the remaining undocumented data types
The language collection described several types only in passing, or not at all. Close the smaller gaps left over from the Puppet 5.5 import: * Add ScalarData, RichData, Iterable, and Iterator to the abstract data types page, each placed beside the types it belongs with. * Add Runtime, Object, and TypeSet under unusual types. TypeSet is the spelling OpenVox renders, though the parser accepts any capitalization, and a module publishes one from types/init_typeset.pp. * Index Sensitive under core data types, and NotUndef, Init, and the seven types above under abstract data types, in lang_data_type.md. All were either documented but unlisted, or absent entirely. * Document the Boolean[true] and Boolean[false] parameters. The page said Boolean "accepts no parameters", which is incorrect. Documenting the parent types turned up three errors in the existing text, corrected here: * Scalar was described as equivalent to Variant[Integer, Float, String, Boolean, Regexp]. In OpenVox 8 it also matches SemVer, SemVerRange, Timestamp, and Timespan, none of which that Variant matches. The equivalence claim is removed rather than restated, since a fixed Variant will drift again as the lattice grows. The SemVer page already contradicted it. * Data was described as matching any value that would match Scalar. It is built on ScalarData, so a regular expression matches Scalar but not Data. * Data's hashes were described as taking keys that match Scalar. Only string keys are accepted; integer, float, and boolean keys are rejected. RichData also omitted several types it matches while Data does not: URI, regular expressions, and resource and class references. Every example and type relationship is verified against OpenVox 8.28.1 with puppet apply. Part of #407 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Signed-off-by: Michael Harp <mike@mikeharp.com>
1 parent 2ec6cd1 commit 34ff616

3 files changed

Lines changed: 167 additions & 5 deletions

File tree

docs/_openvox_8x/lang_data_abstract.md

Lines changed: 128 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ title: "Language: Data types: Abstract data types"
1212
[hashes]: ./lang_data_hash.html
1313
[hash_missing_key_access]: ./lang_data_hash.html#accessing-values
1414
[numbers]: ./lang_data_number.html
15+
[semver]: ./lang_data_semver.html
16+
[uri]: ./lang_data_uri.html
17+
[time]: ./lang_data_time.html
18+
[binary]: ./lang_data_binary.html
19+
[error]: ./lang_data_error.html
20+
[sensitive]: ./lang_data_sensitive.html
21+
[typecasting]: ./lang_typecasting.html
1522

1623
As described in [the Data Type Syntax][types] page, each of Puppet's main [data types][] has a corresponding value that _represents_ that data type, which can be used to match values of that type in several contexts. (For example, `String` or `Array`.)
1724

@@ -257,27 +264,67 @@ The `Scalar` data type matches _all_ values of the following concrete data types
257264
* [Strings][]
258265
* [Booleans][]
259266
* [Regular expressions][]
267+
* [`SemVer` and `SemVerRange`][semver]
268+
* [`Timestamp` and `Timespan`][time]
260269

261270
Note that it doesn't match `undef`, `default`, resource references, arrays, or hashes.
262271

263272
It takes no parameters.
264273

265-
`Scalar` is equivalent to `Variant[Integer, Float, String, Boolean, Regexp]`.
274+
### `ScalarData`
275+
276+
The `ScalarData` data type matches the subset of `Scalar` that can be represented directly in JSON:
277+
278+
* [Numbers][] (both integers and floats)
279+
* [Strings][]
280+
* [Booleans][]
281+
282+
It doesn't match regular expressions, `SemVer`, `SemVerRange`, `Timestamp`, or `Timespan`, all of which
283+
`Scalar` does match. Like `Scalar`, it doesn't match `undef` or `default`.
284+
285+
It takes no parameters.
286+
287+
`ScalarData` is to `Scalar` what `Data` is to `RichData`: the JSON-compatible subset.
266288

267289
### `Data`
268290

269-
The `Data` data type matches any value that would match `Scalar`, but it also matches:
291+
The `Data` data type matches any value that would match `ScalarData`, but it also matches:
270292

271293
* `undef`
272294
* [Arrays][] that only contain values that would also match `Data`
273-
* [Hashes][] whose keys would match `Scalar` and whose values would also match `Data`
295+
* [Hashes][] whose keys are [strings][] and whose values would also match `Data`
274296

275-
Note that it doesn't match `default` or resource references.
297+
Note that it is built on `ScalarData` rather than `Scalar`, so the members of `Scalar` that have no JSON
298+
equivalent are excluded: a regular expression matches `Scalar` but not `Data`. It also doesn't match
299+
`default` or resource references.
276300

277301
It takes no parameters.
278302

279303
`Data` is especially useful because it represents the subset of types that can be directly represented in almost all serialization formats (e.g. JSON).
280304

305+
### `RichData`
306+
307+
The `RichData` data type matches any value that would match `Data`, and also matches the types that have no
308+
direct JSON equivalent:
309+
310+
* [Regular expressions][]
311+
* [`URI`][uri]
312+
* [`Binary`][binary]
313+
* [`Timestamp` and `Timespan`][time]
314+
* [`SemVer` and `SemVerRange`][semver]
315+
* [`Error`][error]
316+
* [`Sensitive`][sensitive]
317+
* Data types themselves, such as `Integer`
318+
* Resource and class references
319+
* `default`
320+
* [Arrays][] and [hashes][] containing any of the above
321+
322+
It takes no parameters.
323+
324+
`RichData` is what a parameter or function should accept when it needs to handle any ordinary Puppet value.
325+
Use `Data` instead when the value has to survive being serialized to JSON, and note that this is the
326+
distinction that makes `Error('boom') =~ Data` false while `Error('boom') =~ RichData` is true.
327+
281328
### `Collection`
282329

283330
The `Collection` type matches _any_ array or hash, regardless of what kinds of values (and/or keys) it contains.
@@ -286,6 +333,40 @@ Note that this means it only partially overlaps with `Data` --- there are values
286333

287334
`Collection` is equivalent to `Variant[Array[Any], Hash[Any, Any]]`.
288335

336+
### `Iterable`
337+
338+
The `Iterable` data type matches any value that an iterative function such as `each` or `map` can walk over.
339+
That includes arrays, hashes, strings, integers, and the `Iterator` values described below:
340+
341+
```puppet
342+
notice([1, 2] =~ Iterable) # true
343+
notice({'a' => 1} =~ Iterable) # true
344+
notice('abc' =~ Iterable) # true
345+
notice(5 =~ Iterable) # true
346+
notice(undef =~ Iterable) # false
347+
```
348+
349+
An optional parameter constrains what the value iterates over, so `Iterable[Integer]` matches only things
350+
that yield integers:
351+
352+
```puppet
353+
notice(5 =~ Iterable[Integer]) # true
354+
```
355+
356+
### `Iterator`
357+
358+
The `Iterator` data type matches the lazy sequences produced by the chained forms of some iterative
359+
functions, such as `reverse_each` and `step` called without a block. Every `Iterator` is also `Iterable`,
360+
but ordinary arrays and hashes are not `Iterator`:
361+
362+
```puppet
363+
notice([1, 2].reverse_each =~ Iterator) # true
364+
notice([1, 2] =~ Iterator) # false
365+
```
366+
367+
Like `Iterable`, it accepts an optional parameter for the type it yields. You rarely write `Iterator`
368+
yourself; it matters mainly when a function returns one and you want to constrain what it produces.
369+
289370
### `Catalogentry`
290371

291372
The `Catalogentry` data type is the parent type of `Resource` and `Class`. This means that, like those types, the Puppet language contains no values that it will ever match. However, the type `Type[Catalogentry]` will match any class reference or resource reference.
@@ -358,3 +439,46 @@ function example(Variant[Integer, Init[Integer]] $x) {
358439
$int_value = Integer($x) # Safe conversion
359440
}
360441
```
442+
443+
See [typecasting][] for the conversions `Init` tests against.
444+
445+
### `Runtime`
446+
447+
The `Runtime` data type matches values that belong to the implementation language underneath Puppet rather
448+
than to the Puppet language itself. It takes the runtime name and the type name within it:
449+
450+
```puppet
451+
Runtime['ruby', 'Symbol']
452+
```
453+
454+
You cannot create such a value in a manifest. The type exists so that Ruby functions and types can describe
455+
arguments that are Ruby objects with no Puppet equivalent, and so those arguments can be type-checked.
456+
457+
### `Object`
458+
459+
The `Object` data type is the parent of types created with the Pcore object model, which is how modules
460+
define types that have named attributes and their own methods. An object type is declared by passing a hash
461+
that names it and lists its attributes:
462+
463+
```puppet
464+
$greeter = Object[{name => 'Greeter', attributes => {greeting => String}}]
465+
$g = $greeter.new('hello')
466+
467+
notice($g.greeting) # hello
468+
notice($g =~ $greeter) # true
469+
```
470+
471+
In practice you rarely write this form inline. Modules declare object types in their `types` directory, one
472+
type per file.
473+
474+
### `TypeSet`
475+
476+
The `TypeSet` data type groups several object types together under one name and version, so a module can
477+
publish a related family of types rather than a loose collection. A type set records a name, a version, and
478+
the types it contains.
479+
480+
A module publishes one by declaring it in `types/init_typeset.pp`, which OpenVox loads as the type set named
481+
after the module. Type sets are not written inline in a manifest.
482+
483+
The type parser accepts any capitalization, so `Typeset` also works, but `TypeSet` is the spelling OpenVox
484+
itself uses when it renders the type.

docs/_openvox_8x/lang_data_boolean.md

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,26 @@ If you want to convert other values to booleans with more permissive rules (`0`
3333

3434
The [data type][] of boolean values is `Boolean`.
3535

36-
It matches only the values `true` or `false`, and accepts no parameters.
36+
On its own it matches only the values `true` or `false`.
3737

38+
### Parameters
39+
40+
`Boolean` takes an optional parameter that narrows it to one of the two values:
41+
42+
```puppet
43+
notice(true =~ Boolean[true]) # true
44+
notice(false =~ Boolean[true]) # false
45+
notice(false =~ Boolean[false]) # true
46+
```
47+
48+
This is useful when a parameter must be one specific value rather than either, such as a flag that may only
49+
ever be switched on:
50+
51+
```puppet
52+
class example (
53+
Boolean[true] $must_be_enabled = true,
54+
) { }
55+
```
3856

3957
### Related data types
4058

docs/_openvox_8x/lang_data_type.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,16 @@ title: "Language: Data types: Data type syntax"
3636
[catalogentry]: ./lang_data_abstract.html#catalogentry
3737
[any]: ./lang_data_abstract.html#any
3838
[callable]: ./lang_data_abstract.html#callable
39+
[sensitive]: ./lang_data_sensitive.html
40+
[notundef]: ./lang_data_abstract.html#notundef
41+
[init]: ./lang_data_abstract.html#init
42+
[scalardata]: ./lang_data_abstract.html#scalardata
43+
[richdata]: ./lang_data_abstract.html#richdata
44+
[iterable]: ./lang_data_abstract.html#iterable
45+
[iterator]: ./lang_data_abstract.html#iterator
46+
[runtime]: ./lang_data_abstract.html#runtime
47+
[object]: ./lang_data_abstract.html#object
48+
[typeset]: ./lang_data_abstract.html#typeset
3949

4050
Each value in the Puppet language has a data type, like "string." There is also a set of values _whose data type is "data type."_
4151

@@ -158,6 +168,7 @@ These are the "real" data types, which make up the most common values you'll int
158168
* [`Timestamp` and `Timespan`][time]
159169
* [`SemVer` and `SemVerRange`][semver]
160170
* [`Error`][error]
171+
* [`Sensitive`][sensitive]
161172
* [`Undef`][undef]
162173
* [`Default`][default]
163174

@@ -173,18 +184,27 @@ Resource references and class references are implemented as data types, although
173184
Abstract data types let you do more sophisticated or permissive type checking.
174185

175186
* [`Scalar`][Scalar]
187+
* [`ScalarData`][ScalarData]
176188
* [`Collection`][Collection]
177189
* [`Variant`][Variant]
178190
* [`Data`][Data]
191+
* [`RichData`][RichData]
179192
* [`Pattern`][Pattern]
180193
* [`Enum`][Enum]
181194
* [`Tuple`][Tuple]
182195
* [`Struct`][Struct]
183196
* [`Optional`][Optional]
197+
* [`NotUndef`][NotUndef]
184198
* [`Catalogentry`][Catalogentry]
185199
* [`Type`][inpage_type]
186200
* [`Any`][Any]
187201
* [`Callable`][Callable]
202+
* [`Init`][Init]
203+
* [`Iterable`][Iterable]
204+
* [`Iterator`][Iterator]
205+
* [`Runtime`][Runtime]
206+
* [`Object`][Object]
207+
* [`TypeSet`][TypeSet]
188208

189209
## The `Type` data type
190210

0 commit comments

Comments
 (0)