YAMLScript Syntax Modes

One of the most important things to understand when learning YAMLScript is the concept of "modes".

It basically comes down to whether an unquoted scalar like count should be considered as a data string or a code symbol (variable, function name etc). Since YAMLScript's main focus is about embedding code into YAML data files, it's very important to know what mode you are in at any given point.

YAMLScript has 3 modes:

  • Bare mode
  • Data mode
  • Code mode

The important one to learn about are data and code modes. To use YAMLScript effectively you'll need to be comfortable with switching back and forth between data the two.

Bare mode is the default when you haven't added a !yamlscript tag to the start of a YAML document. It means that everything in the file is data; code can never be used. This is how we can make sure that existing YAML files are valid YAMLScript.

To enable a YAML file to use YAMLScript code, you need to add one of these tags to the top:

  • !yamlscript/v0/code - Start in code mode.
  • !yamlscript/v0/data - Start in data mode.
  • !yamlscript/v0 - Short for !yamlscript/v0/code
  • !yamlscript/v0/ - Short for !yamlscript/v0/data

Consider the following examples.

Bare mode:

$ ys --load <(echo '
foo:
count: [red, green, blue]')
{"foo":{"count":["red","green","blue"]}}

Data mode:

$ ys --load <(echo '
!yamlscript/v0/
foo:
count: [red, green, blue]')
{"foo":{"count":["red","green","blue"]}}

Code mode:

$ ys --load <(echo '
!yamlscript/v0
foo:
count: [red, green, blue]')
Error: Sequences (block and flow) not allowed in code mode

Oops. Looks like we need to switching to data mode in there.

Switching Modes

If we want to add a function to a data file we should start in data mode. Then we should switch to code mode for things that are code.

Here we want to call the count function with a sequence and get back 3, the number of elements in the sequence.

The special tag ! can be used to switch from data to code and vice versa.

$ ys --load <(echo '
!yamlscript/v0/
foo: !
count: [red, green, blue]')
Error: Sequences (block and flow) not allowed in code mode

Here we started in data mode but then switched the mode to code with !. We got the same error. YAMLScript only allows block mappings for code. We need to put [red, green, blue] into data mode:

$ ys --load <(echo '
!yamlscript/v0/
foo: !
count: ! [red, green, blue]')
{"foo":3}

It worked!

Using ! is so common that YAMLScript has a cleaner way to do it when used on a mapping pair value. If you use :: instead of : it does the same thing.

Let's try it out:

$ ys --load <(echo '
!yamlscript/v0/
foo::
count:: [red, green, blue]')
{"foo":3}

Sweet!

However, when switching in a sequence you'll need to use !:

$ ys --load <(echo '
!yamlscript/v0/
- !
count:: [red, green, blue]')
[3]

NOTE: :: isn't special YAML syntax. YAMLScript cannot change YAML 1.2 syntax in any way. In the examples above count: is simply a plain scalar ending with :.

We can see that in bare mode:

$ ys --load <(echo '
count:: [red, green, blue]')
{"count:":["red","green","blue"]}