YS YAML Documents
YAML files (aka YAML streams) can contain multiple "documents".
A YAML document is a top level mapping or sequence "node".
Most YAML files contain a single document, but YAML files can contain multiple
(or zero!) documents.
New documents are started with a line of three dashes: ---
.
YS can put these documents to all kinds of good use.
When you "load" a YAML file with YS, the result is the evaluation of the final document (by default). But since YS is functional, it can access any of the other documents.
Let's continue with yesterday's shoes example.
Anchors Up🔗
One of the (unfortunate, imho) rules of YAML is that you can't use aliases to reference anchored nodes in other documents.
$ ys -Y - <<<'
--- &number 7
---
lucky: *number
'
Error: Anchor not found: &number
Since YS follows the the rules of the YAML 1.2 spec, it can't do what we want here. This is just a plain old YAML "stream" (complete YAML file or string).
What happens if we supercharge things with the YS !YS-v0
tag?
$ ys -Y - <<<'
--- &number 7
--- !YS-v0:
lucky: *number
'
lucky: 7
Nice!
Enabling YS for a document allowed us to play by YS rules and access (alias) anchored nodes in other documents. That's handy.
But wait.
Why did we use !YS-v0:
instead of just !YS-v0
?
!YS-v0
- This document is YS code. (start in code mode)!YS-v0:
- This doc is data, but YS magics are enabled. (start in data mode)- Documents without either are just plain YAML. No YS magics. (bare mode)
We'll talk more about mode setting tags in a future post.
New shoes!🔗
Let's take what we just learned and refactor our shoes example.
# shoes.yaml
--- &defaults
size: 10
color: blue
--- !YS-v0:
- name: sneaker
<<: *defaults
color: red
- name: boot
<<: *defaults
color: black
- name: sandal
size: 8
<<: *defaults
And now load it:
$ ys -J shoes.yaml
[{"name":"sneaker", "color":"red", "size":10},
{"name":"boot", "color":"black", "size":10},
{"name":"sandal", "size":8, "color":"blue"}]
That's cleaner than yesterday's examples.
Docs and Variables🔗
Anchors are OK, but they're a bit noisy compared to variables.
For fun, let's try using both with multiple documents.
---
- &size 10
- &color blue
--- !YS-v0
defaults =::
color: *color
size: *size
--- !YS-v0:
- name: sneaker
<<:: defaults
color: red
- name: boot
<<:: defaults
color: black
- name: sandal
size: 8
<<:: defaults
Then:
$ ys -J shoes.yaml
[{"name":"sneaker", "color":"red", "size":10},
{"name":"boot", "color":"black", "size":10},
{"name":"sandal", "size":8, "color":"blue"}]
This example is somewhat contrived, but it shows off most everything we've talked about so today.
We have 3 documents here.
In the first document, instead of anchoring the defaults mapping, we anchored the size and color values. This document had no starting tag, so it's plain old YAML (bare mode).
Next, we used a code mode document to define a variable named defaults
which
contains the size and color values.
It got the values by aliasing the size and color values from a different
document.
Note the use of =::
(extra colon) to switch to data mode to define the
mapping.
Finally we have our data mode document that produces the mapping we want.
It references the defaults
variable we defined in the previous document by
using ::
to switch over to code mode when needed.
Pretty cool.
Walking in these Shoes🔗
There's a few more interesting topics we can get into using the shoes example.
If this is all seeming too simple, believe me, we'll be getting into some deep waters this summer. Patience, young hacker.
A YS guy once said:
"The journey of 92 days begins with a few steps in these shoes."
See you tomorrow!