Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

I don't understand what a YAML tag is

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".

like image 334
Fred Avatar asked Mar 05 '13 20:03

Fred


People also ask

What is a YAML tag?

YAML (/ˈjæməl/ and YAH-ml) (see § History and name) is a human-readable data-serialization language. It is commonly used for configuration files and in applications where data is being stored or transmitted.

How do I read a YAML file?

YAML is a digestible data serialization language often used to create configuration files with any programming language. Designed for human interaction, YAML is a strict superset of JSON, another data serialization language. But because it's a strict superset, it can do everything that JSON can and more.

Which of the following types are used for YAML tag repository?

YAML represents the data structure using three kinds of nodes: sequence, mapping and scalar.

Why is YAML so popular?

It is more human-readable. YAML allows you to represent complex data structures in a human-readable format. It is unambiguous. YAML unambiguously specifies the data structures of the serialized data, so there's no need to rely on comments or documentation.


1 Answers

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

like image 75
Alex Avatar answered Oct 17 '22 22:10

Alex