135

The <<: operator in YAML is usable to import the contents of one mapping into another, similarly to the ** double-splat operator in Python or ... object destructuring operator in JavaScript. For example,

foo:
  a: b
  <<:
    c: d
  e: f

is equivalent to

foo:
  a: b
  c: d
  e: f

This is useful when used along with node anchors to include some common default properties in many objects, as illustrated in, for example, the Learn YAML in Y minutes tutorial:

# Anchors can be used to duplicate/inherit properties
base: &base
    name: Everyone has same name

foo: &foo
    <<: *base
    age: 10

bar: &bar
    <<: *base
    age: 20

However, I am confused about where this syntax comes from or why it works. CTRL + Fing the YAML specification for << reveals that it doesn't appear anywhere in the specification. Yet it's supported by, at the very least, PyYAML and Online YAML Parser.

What is this syntax, and how come it doesn't seem to appear in the specification?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mark Amery
  • 143,130
  • 81
  • 406
  • 459
  • 6
    It is not a `<<:` operator it is a specific key `<<` in a key value pair. The `:` is the normal key-value separator. – Anthon Dec 09 '16 at 17:07

2 Answers2

113

It is called the Merge Key Language-Independent Type for YAML version 1.1. and specified here.

It is something that parsers can optionally support, and it is essentially an interpretation of the key-value pair with the special key <<, where the value is either a mapping (usually indicated via an alias as in the spec, and although that doesn't seem to be required, it makes little sense not to use an alias) or a list of mappings (i.e., aliases of mappings), and gets interpreted in a special way.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Anthon
  • 69,918
  • 32
  • 186
  • 246
  • 5
    Thanks, was looking for quite some time after this. I guess calling it destructuring would have been too easy – gyozo kudor Jan 20 '21 at 11:11
  • 1
    Just note that current [merge type spec](https://yaml.org/type/merge.html) is still sub-titled *Working Draft 2005-01-18*, and not mentioned even in the current [YAML 1.2.2 spec](https://yaml.org/spec/1.2.2/). – mykhal Jul 28 '22 at 18:52
65

To add on to other answers:

IMO, the example from "Learn YAML in Y Minutes" is incomplete, because it doesn't show what happens when the keys are the same. For example:

base: &base
    name: Everyone has same name
    age: 5

foo: &foo
    <<: *base

bar: &bar
    <<: *base
    age: 20

For the bottom two items, it yields:

foo:
    name: Everyone has same name
    age: 5

bar:
    name: Everyone has same name
    age: 20

bar overrides the age while foo does not. According to the spec, the entries of the object merging in have a lower priority than those on the object receiving them.

The “<<” merge key is used to indicate that all the keys of one or more specified maps should be inserted into the current map. If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the current mapping, unless the key already exists in it.

xdhmoore
  • 8,935
  • 11
  • 47
  • 90
  • What if we import ("merge") multiple objects that have same key within? which one will have the "lower priority"? There's no significance to the order of merging, order of object creations, etc? And, the "resolution" methodology specified by YAML is mandatory, or maybe can be overridden, conceptually? (as it's not a programming language, but more declarative format, yet provide some functional capabilities) – Reflection Dec 29 '22 at 20:53
  • 1
    To be clear, I try to understand how the specification handles the "Diamond Problem" of multiple-inheritance (wikipedia: https://en.wikipedia.org/wiki/Multiple_inheritance#The_diamond_problem). If we have object A with key named X, and other object B with key named X as well, and object C that merges both A and B into itself, which X will be used? – Reflection Dec 29 '22 at 21:04
  • 1
    @Reflection: From the [Merge Key spec](https://yaml.org/type/merge.html): "Keys in mapping nodes earlier in the sequence override keys specified in later mapping nodes.". So if object C merges A and B (in that order) then C will get A's X. – Michael Burr Feb 16 '23 at 06:31