I don't understand what a YAML tag is

TagsYamlSpecificationsPyyaml

Tags Problem Overview


I get it on some level, but I have yet to see an example that didn't bring up more questions than answers.

http://rhnh.net/2011/01/31/yaml-tutorial

# Set.new([1,2]).to_yaml
--- !ruby/object:Set 
hash: 
  1: true
  2: true

I get that we're declaring a Set tag. I don't get what the subsequent hash mapping has to do with it. Are we declaring a schema? Can someone show me an example with multiple tag declarations?

I've read through the spec: http://yaml.org/spec/1.2/spec.html#id2761292

%TAG ! tag:clarkevans.com,2002:

Is this declaring a schema? Is there something else a parser has to do in order to successfully parse the file? A schema file of some type?

http://www.yaml.org/refcard.html

Tag property: # Usually unspecified.
    none    : Unspecified tag (automatically resolved by application).
    '!'     : Non-specific tag (by default, "!!map"/"!!seq"/"!!str").
    '!foo'  : Primary (by convention, means a local "!foo" tag).
    '!!foo' : Secondary (by convention, means "tag:yaml.org,2002:foo").
    '!h!foo': Requires "%TAG !h! <prefix>" (and then means "<prefix>foo").
    '!<foo>': Verbatim tag (always means "foo").

Why is it relevant to have a primary and secondary tag, and why does a secondary tag refer to a URI? What problem is being solved by having these?

I seem to see a lot of "what they are", and no "why are they there", or "what are they used for".

Tags Solutions


Solution 1 - Tags

I don't know a lot about YAML but I'll give it a shot:

Tags are used to denote types. A tag is declared using ! as you have seen from the "refcard" there. The %TAG directive is kind of like declaring a shortcut to a tag.

I'll demonstrate with PyYaml. PyYaml can parse the secondary tag of !!python/object: as an actual python object. The double exclamation mark is a substitution in itself, short for !tag:yaml.org,2002:, which turns the whole expression into !tag:yaml.org,2002:python/object:. This expression is a little unwieldy to be typing out every time we want to create an object, so we give it an alias using the %TAG directive:

%TAG !py! tag:yaml.org,2002:python/object:            # declares the tag alias
---
- !py!__main__.MyClass                                # creates an instance of MyClass

- !!python/object:__main__.MyClass                    # equivalent with no alias

- !<tag:yaml.org,2002:python/object:__main__.MyClass> # equivalent using primary tag

Nodes are parsed by their default type if you have no tag annotations. The following are equivalent:

- 1: Alex
- !!int "1": !!str "Alex"

Here is a complete Python program using PyYaml demonstrating tag usage:

import yaml

class Entity:
    def __init__(self, idNum, components):
        self.id = idNum
        self.components = components
    def __repr__(self):
         return "%s(id=%r, components=%r)" % (
             self.__class__.__name__, self.id, self.components)

class Component:
    def __init__(self, name):
        self.name = name
    def __repr__(self):
        return "%s(name=%r)" % (
            self.__class__.__name__, self.name)

text = """
%TAG !py! tag:yaml.org,2002:python/object:__main__.
---
- !py!Component &transform
  name: Transform
  
- !!python/object:__main__.Component &render
  name: Render

- !<tag:yaml.org,2002:python/object:__main__.Entity>
  id: 123
  components: [*transform, *render]

- !<tag:yaml.org,2002:int> "3"
"""

result = yaml.load(text)

More information is available in the spec

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionFredView Question on Stackoverflow
Solution 1 - TagsAlexView Answer on Stackoverflow