daemonl

In case you were wondering...

YAML - Anchors, References, Extend

YAML is pretty cool for config files. I don't think it should be used 'on the wire' - I suppose you could, but it's more for people than machines.

Most of YAML can be converted into JSON, and I would say most applications use it that way.

Basics

---
foo: bar
baz:
 - "thing1"
 - "thing2"
# I am a comment

Again in JSON

{
  "foo": "bar",
  "baz": [
    "thing1",
    "thing2"
  ]
}

More here: [http://docs.ansible.com/ansible/YAMLSyntax.html]

But that's not all, YAML can solve a little bit of the DRY problem too.

Anchors and References. & *

---
foo: &anchor
 K1: "One"
 K2: "Two"

bar: *anchor
{
    "foo": {
        "K1": "One",
        "K2": "Two"
    },
    "bar": {
        "K1": "One",
        "K2": "Two"
    }
}

The & defines and names an anchor, and the * uses it.

Which probably seems more useful than it is - you can only clone exact replicas.

Extend <<

But wait, there's more. You can extend objects as well

---
foo: &anchor
  K1: "One"
  K2: "Two"

bar:
  <<: *anchor
  K2: "I Changed"
  K3: "Three"
{
    "foo": {
        "K1": "One",
        "K2": "Two"
    },
    "bar": {
        "K1": "One",
        "K2": "I Changed",
        "K3": "Three"
    }
}

The << marker means extend, so <<: *anchor means, basically, inject anchor into bar, then extend

So a strange note, a lot of the parsers written in node.js break here - they actually modify foo. Use something written in Python.

python -c 'import sys, yaml, json; json.dump(yaml.load(sys.stdin), sys.stdout, indent=4)' < in.yaml > out.json

Extend Inline

But Wait, there's STILL MORE!

What if you wanted to take only SOME keys from foo and inject them into bar? Well - now you can!

---
foo:
 <<: &anchor
   K1: "One"
 K2: "Two"

bar:
 <<: *anchor
 K3: "Three"
{
    "foo": {
        "K1": "One",
        "K2": "Two"
    }, 
    "bar": {
        "K1": "One",
        "K3": "Three"
    }
}

What we have done there is inject a new object into foo, AND save it as an anchor, which we can then use to inject the same object into bar.

Cool, right?!

Extra Credit

Bash Alias

Add this baby to your .bashrc or .profile or whatever you use

alias yaml2js="python -c 'import sys, yaml, json; json.dump(yaml.load(sys.stdin), sys.stdout, indent=4)'"

And you have yourself a new command.

yaml2js < in.yaml > out.json
# or
cat in.yaml | yaml2js > out.json
# Or your perferred brand of ninjery