2013-03-05 20 views
21

Lo capisco a un certo livello, ma devo ancora vedere un esempio che non ha sollevato più domande che risposte.Non capisco cosa sia un tag YAML

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

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

ottengo che stiamo dichiarando un tag set. Non capisco che cosa abbia a che fare il successivo hash mapping con esso. Stiamo dichiarando uno schema? Qualcuno può mostrarmi un esempio con più dichiarazioni di tag?

Ho letto attraverso la specifica: http://yaml.org/spec/1.2/spec.html#id2761292

%TAG ! tag:clarkevans.com,2002: 

È questo dichiarando uno schema? C'è qualcos'altro che un parser deve fare per analizzare correttamente il file? Un file di schema di qualche tipo?

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

Perché è rilevante per avere un tag primario e secondario, e perché un tag secondario si riferiscono a un URI? Quale problema viene risolto avendo questi?

Mi sembra di vedere un sacco di "cosa sono" e no "perché sono lì" o "per cosa sono usati".

+2

Nel vostro primo esempio, '# Imposta. new ([1,2]). to_yaml' è in realtà un * commento * - è un'affermazione ruby ​​che produrrebbe lo YAML sotto di esso. – AlexFoxGill

risposta

13

non so molto su YAML, ma ho deciso di dargli un colpo:

tag vengono utilizzati per indicare i tipi. Un tag è dichiarato usando ! come si vede dalla "refcard" lì. La direttiva %TAG è un po 'come dichiarare un collegamento a un tag.

Mostrerò con PyYaml. PyYaml può analizzare il tag secondario di !!python/object: come un vero oggetto python. Il doppio punto esclamativo è una sostituzione in sé, abbreviazione di !tag:yaml.org,2002:, che trasforma l'intera espressione in !tag:yaml.org,2002:python/object:. Questa espressione è un po 'ingombrante per essere digitando fuori ogni volta che vogliamo creare un oggetto, in modo da dare un alias utilizzando la direttiva %TAG:

%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 

I nodi vengono analizzati per il loro tipo di default se non si hanno le annotazioni tag . I seguenti sono equivalenti:

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

Ecco un programma completo Python utilizzando PyYaml dimostrando l'utilizzo di tag:

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) 

Ulteriori informazioni sono disponibili nel spec