Load and Compose your YAML Files
Probably the biggest problem people have with YAML is that everything has to be in one file. Things start off nice and clean, but as requirements grow, so do your files!
What if you could compose your YAML documents like you compose your code? Lots of small, single-purpose, possibly reusable files that you can load and compose together into the thing you need?
That's what YS is all about. As you know, YS is a functional language, and it has quite a few ways to load data (and code too, since Code is Data™!) from external sources.
Today we'll be looking at how to load things from disk files, including:
- Other YS files
- YAML files (YAML is YS)
- JSON files (JSON is YAML)
You can also load things from CSV/TSV files, shell commands, databases, APIs, environment variables, and the web, but those are topics for another day.
Loading YAML Files🔗
YS has a standard library function called load
that can load YS files.
Since YAML is YS, you can load YAML files with load
.
And since JSON is YAML, you can also load JSON files with load
.
Let's try on some new shoes!
We'll put each shoe in its own file.
# shoe1.yaml
name: sneaker
color: red
# shoe2.json
{
"name": "boot",
"color": "black"
}
# shoe3.ys
!YS-v0:
name: sandal
size:: 2 * 2 * 2
I got a little cheeky on that third shoe. I used a YS expression to calculate the size! That's just to show that YS expressions evaluate on load.
Let's load them all together.
# shoes.yaml
!YS-v0:
- ! load('shoe1.yaml')
- ! load('shoe2.json')
- ! load('shoe3.ys')
Notice the !
there?
Remember the ::
mode switcher?
Well ::
is just a nice shorthand for !
.
It works great with mapping pairs, but for sequence entries, there's no way to
use it, so we need to use !
instead.
$ ys -Y shoes.yaml
- name: sneaker
color: red
- name: boot
color: black
- name: sandal
size: 8
It works, but we don't have the defaults in there.
We'll make a defaults file like this:
# defaults.yaml
size: 10
color: blue
Now we could use the merge key (<<
) to add it to the YAML and YS files,
but that would never work in a JSON file.
Fortunately, YS is a functional language with 100s of functions.
Surely it has a merge
function!
# shoes.yaml
!YS-v0:
- ! merge(load('defaults.yaml'), load('shoe1.yaml'))
- ! merge(load('defaults.yaml'), load('shoe2.json'))
- ! merge(load('defaults.yaml'), load('shoe3.ys'))
And then:
$ ys -Y shoes.yaml
- size: 10
color: red
name: sneaker
- size: 10
color: black
name: boot
- size: 8
color: blue
name: sandal
There we go!
There's More Than One Way To Do It🔗
I was raised by Perl wolves! (well, Monks in wolf's clothing)
As we progress through the Summer of YS, you'll notice Perlisms showing up here and there. For all its warts, Perl is has a lot of gems. Maybe that's what Matz was thinking when he created Ruby and based so much of it on Perl? I've stolen many of those shiniest gems for YS.
Anyway, in YS… TMTOWTDI!
Let's rearrange our new shoes a bit:
--- !YS-v0
defaults =:
load: 'defaults.yaml'
--- !YS-v0:
- ! defaults.merge(load('shoe1.yaml'))
- !
merge defaults:
load: 'shoe2.json'
- !:merge*
- ! defaults
- ! load('shoe3.ys')
And we get:
$ ys -Y shoes.yaml
- size: 10
color: red
name: sneaker
- size: 10
color: black
name: boot
- size: 8
color: blue
name: sandal
That's a lot of new YS syntax to unpack, but the surf's up!
See you again tomorrow!