# module Syck

## YAML¶ ↑

YAML(tm) (rhymes with 'camel') is a straightforward machine parsable data serialization format designed for human readability and interaction with scripting languages such as Perl and Python. YAML is optimized for data serialization, formatted dumping, configuration files, log files, Internet messaging and filtering. This specification describes the YAML information model and serialization format. Together with the Unicode standard for characters, it provides all the information necessary to understand YAML Version 1.0 and construct computer programs to process it.

See yaml.org/ for more information. For a quick tutorial, please visit YAML In Five Minutes (yaml.kwiki.org/?YamlInFiveMinutes).

## About This Library¶ ↑

The YAML 1.0 specification outlines four stages of YAML loading and dumping. This library honors all four of those stages, although data is really only available to you in three stages.

The four stages are: native, representation, serialization, and presentation.

The native stage refers to data which has been loaded completely into Ruby's own types. (See `YAML::load`.)

The representation stage means data which has been composed into `YAML::BaseNode` objects. In this stage, the document is available as a tree of node objects. You can perform YPath queries and transformations at this level. (See `YAML::parse`.)

The serialization stage happens inside the parser. The YAML parser used in Ruby is called Syck. Serialized nodes are available in the extension as SyckNode structs.

The presentation stage is the YAML document itself. This is accessible to you as a string. (See `YAML::dump`.)

For more information about the various information models, see Chapter 3 of the YAML 1.0 Specification (yaml.org/spec/#id2491269).

The YAML module provides quick access to the most common loading (YAML::load) and dumping (YAML::dump) tasks. This module also provides an API for registering global types (YAML::add_domain_type).

## Example¶ ↑

A simple round-trip (load and dump) of an object.

    require "yaml"

    test_obj = ["dogs", "cats", "badgers"]

    yaml_obj = YAML::dump( test_obj )
                        # -> ---
                             - dogs
                             - cats
                             - badgers
    ruby_obj = YAML::load( yaml_obj )
                        # => ["dogs", "cats", "badgers"]
    ruby_obj == test_obj
                        # => true

To register your custom types with the global resolver, use `add_domain_type`.

    YAML::add_domain_type( "your-site.com,2004", "widget" ) do |type, val|
        Widget.new( val )
    end

YAML::BaseNode class

Constants used throughout the library

Handle Unicode-to-Internal conversion

Error messages and exception class

YAML::Loader class .. type handling ..

$Id$

# yaml/tag.rb: methods for associating a taguri to a class.¶ ↑

Author

  why the lucky stiff

Classes required by the full core typeset

### Constants

DEFAULTS

  Default settings

DNS_COMP_RE
DNS_NAME_RE
ERROR_ANCHOR_ALIAS
ERROR_BAD_ALIAS
ERROR_BAD_ANCHOR
ERROR_BAD_EXPLICIT
ERROR_MANY_ALIAS
ERROR_MANY_ANCHOR
ERROR_MANY_EXPLICIT
ERROR_MANY_IMPLICIT
ERROR_NEED_HEADER
ERROR_NO_ANCHOR
ERROR_NO_HEADER_NODE

  Error messages

ERROR_UNSUPPORTED_ENCODING
ERROR_UNSUPPORTED_VERSION
ERROR_ZERO_INDENT
ESCAPES
ESCAPE_CHAR
INDICATOR_CHAR
NOT_PLAIN_CHAR
PRINTABLE_CHAR
RESTRICTED_INDICATORS
SPACE_INDICATORS
SUPPORTED_YAML_VERSIONS
UNESCAPES
VERSION

  Constants

WORD_CHAR

  Parser tokens

### Public Class Methods

add_builtin_type( type_tag, &transfer_proc ) click to toggle source

Add a transfer method for a builtin type

    # File lib/syck.rb, line 317
    def self.add_builtin_type( type_tag, &transfer_proc )
        resolver.add_type( "tag:yaml.org,2002:#{ type_tag }", transfer_proc )
    end

add_domain_type( domain, type_tag, &transfer_proc ) click to toggle source

Add a global handler for a YAML domain type.

    # File lib/syck.rb, line 310
    def self.add_domain_type( domain, type_tag, &transfer_proc )
        resolver.add_type( "tag:#{ domain }:#{ type_tag }", transfer_proc )
    end

add_private_type( type_re, &transfer_proc ) click to toggle source

Add a private document type

    # File lib/syck.rb, line 332
    def self.add_private_type( type_re, &transfer_proc )
        warn "#{caller[0]}: YAML.add_private_type is deprecated, use add_domain_type" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        resolver.add_type( "x-private:" + type_re, transfer_proc )
    end

add_ruby_type( type_tag, &transfer_proc ) click to toggle source

Add a transfer method for a builtin type

    # File lib/syck.rb, line 324
    def self.add_ruby_type( type_tag, &transfer_proc )
        warn "#{caller[0]}: YAML.add_ruby_type is deprecated, use add_domain_type" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", transfer_proc )
    end

detect_implicit( val ) click to toggle source

Detect typing of a string

    # File lib/syck.rb, line 340
    def self.detect_implicit( val )
        warn "#{caller[0]}: YAML.detect_implicit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        resolver.detect_implicit( val )
    end

dump( obj, io = nil ) click to toggle source

Converts obj to YAML and writes the YAML result to io.

    File.open( 'animals.yaml', 'w' ) do |out|
      YAML.dump( ['badger', 'elephant', 'tiger'], out )
    end

If no io is provided, a string containing the dumped YAML is returned.

    YAML.dump( :locked )
       #=> "--- :locked"

    # File lib/syck.rb, line 124
    def self.dump( obj, io = nil )
        obj.to_yaml( io || io2 = StringIO.new )
        io || ( io2.rewind; io2.read )
    end

dump_stream( *objs ) click to toggle source

Returns a YAML stream containing each of the items in `objs`, each having their own document.

    YAML.dump_stream( 0, [], {} )
      #=> --- 0
          --- []
          --- {}

    # File lib/syck.rb, line 299
    def self.dump_stream( *objs )
        d = Stream.new
        objs.each do |doc|
            d.add( doc )
        end
        d.emit
    end

each_document( io, &block ) click to toggle source

Calls block with each consecutive document in the YAML stream contained in io.

    File.open( 'many-docs.yaml' ) do |yf|
      YAML.each_document( yf ) do |ydoc|
        ## ydoc contains the single object
        ## from the YAML document
      end
    end

    # File lib/syck.rb, line 224
    def self.each_document( io, &block )
        warn "#{caller[0]}: YAML.each_document is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        parser.load_documents( io, &block )
    end

each_node( io, &doc_proc ) click to toggle source

Calls block with a tree of `YAML::BaseNodes`, one tree for each consecutive document in the YAML stream contained in io.

    File.open( 'many-docs.yaml' ) do |yf|
      YAML.each_node( yf ) do |ydoc|
        ## ydoc contains a tree of nodes
        ## from the YAML document
      end
    end

    # File lib/syck.rb, line 255
    def self.each_node( io, &doc_proc )
        warn "#{caller[0]}: YAML.each_node is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        generic_parser.load_documents( io, &doc_proc )
    end

emitter() click to toggle source

Returns a new default emitter

    # File lib/syck.rb, line 106
    def self.emitter
        warn "#{caller[0]}: YAML.emitter is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        Emitter.new.set_resolver( self.resolver )
    end

escape( value, skip = "" ) click to toggle source

Escape the string, condensing common escapes

    # File lib/syck/encoding.rb, line 10
    def self.escape( value, skip = "" )
          warn "#{caller[0]}: YAML.escape is deprecated" if $VERBOSE
            value.gsub( /\\/, "\\\\\\" ).
          gsub( /"/, "\\\"" ).
          gsub( /([\x00-\x1f])/ ) do
             skip[$&] || ESCAPES[ $&.unpack("C")[0] ]
         end
    end

generic_parser() click to toggle source

Returns a new generic parser

    # File lib/syck.rb, line 94
    def self.generic_parser
        warn "#{caller[0]}: YAML.generic_parser is deprecated, switch to psych" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        Parser.new.set_resolver( GenericResolver )
    end

load( io ) click to toggle source

Load a document from the current io stream.

    File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }
       #=> ['badger', 'elephant', 'tiger']

Can also load from a string.

    YAML.load( "--- :locked" )
       #=> :locked

    # File lib/syck.rb, line 140
    def self.load( io )
        parser.load( io )
    end

load_documents( io, &doc_proc ) click to toggle source

Calls block with each consecutive document in the YAML stream contained in io.

    File.open( 'many-docs.yaml' ) do |yf|
      YAML.load_documents( yf ) do |ydoc|
        ## ydoc contains the single object
        ## from the YAML document
      end
    end

    # File lib/syck.rb, line 240
    def self.load_documents( io, &doc_proc )
        parser.load_documents( io, &doc_proc )
    end

load_file( filepath ) click to toggle source

Load a document from the file located at filepath.

    YAML.load_file( 'animals.yaml' )
       #=> ['badger', 'elephant', 'tiger']

    # File lib/syck.rb, line 150
    def self.load_file( filepath )
        File.open( filepath ) do |f|
            load( f )
        end
    end

load_stream( io ) click to toggle source

Loads all documents from the current io stream, returning a `YAML::Stream` object containing all loaded documents.

    # File lib/syck.rb, line 281
    def self.load_stream( io )
        d = nil
        parser.load_documents( io ) do |doc|
            d = Stream.new if not d
            d.add( doc )
        end
        return d
    end

make_stream( io ) click to toggle source

Class method for creating streams

    # File lib/syck/stringio.rb, line 57
    def Syck.make_stream( io )
    if String === io
        io = StringIO.new( io )
    elsif not IO === io
        raise Syck::Error, "YAML stream must be an IO or String object."
    end
    if Syck::unicode
        def io.readline
            Syck.utf_to_internal( readline( @ln_sep ), @utf_encoding )
        end
        def io.check_unicode
            @utf_encoding = Syck.sniff_encoding( read( 4 ) )
            @ln_sep = Syck.enc_separator( @utf_encoding )
            seek( -4, IO::SEEK_CUR )
        end
                def io.utf_encoding
                  @utf_encoding
                end
        io.check_unicode
    else
        def io.utf_encoding
            :None
        end
    end
    io
    end

object_maker( obj_class, val ) click to toggle source

Allocate blank object

    # File lib/syck.rb, line 383
    def self.object_maker( obj_class, val )
        warn "#{caller[0]}: YAML.object_maker is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        if Hash === val
            o = obj_class.allocate
            val.each_pair { |k,v|
                o.instance_variable_set("@#{k}", v)
            }
            o
        else
            raise Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect
        end
    end

parse( io ) click to toggle source

Parse the first document from the current io stream

    File.open( 'animals.yaml' ) { |yf| YAML::load( yf ) }
       #=> #<YAML::Syck::Node:0x82ccce0
            @kind=:seq,
            @value=
             [#<YAML::Syck::Node:0x82ccd94
               @kind=:scalar,
               @type_id="str",
               @value="badger">,
              #<YAML::Syck::Node:0x82ccd58
               @kind=:scalar,
               @type_id="str",
               @value="elephant">,
              #<YAML::Syck::Node:0x82ccd1c
               @kind=:scalar,
               @type_id="str",
               @value="tiger">]>

Can also load from a string.

    YAML.parse( "--- :locked" )
       #=> #<YAML::Syck::Node:0x82edddc
             @type_id="tag:ruby.yaml.org,2002:sym",
             @value=":locked", @kind=:scalar>

    # File lib/syck.rb, line 183
    def self.parse( io )
        generic_parser.load( io )
    end

parse_documents( io, &doc_proc ) click to toggle source

Calls block with a tree of `YAML::BaseNodes`, one tree for each consecutive document in the YAML stream contained in io.

    File.open( 'many-docs.yaml' ) do |yf|
      YAML.parse_documents( yf ) do |ydoc|
        ## ydoc contains a tree of nodes
        ## from the YAML document
      end
    end

    # File lib/syck.rb, line 271
    def self.parse_documents( io, &doc_proc )
        warn "#{caller[0]}: YAML.parse_documents is deprecated, use load_stream" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        self.each_node( io, &doc_proc )
    end

parse_file( filepath ) click to toggle source

Parse a document from the file located at filepath.

    YAML.parse_file( 'animals.yaml' )
       #=> #<YAML::Syck::Node:0x82ccce0
            @kind=:seq,
            @value=
             [#<YAML::Syck::Node:0x82ccd94
               @kind=:scalar,
               @type_id="str",
               @value="badger">,
              #<YAML::Syck::Node:0x82ccd58
               @kind=:scalar,
               @type_id="str",
               @value="elephant">,
              #<YAML::Syck::Node:0x82ccd1c
               @kind=:scalar,
               @type_id="str",
               @value="tiger">]>

    # File lib/syck.rb, line 207
    def self.parse_file( filepath )
        File.open( filepath ) do |f|
            parse( f )
        end
    end

parser() click to toggle source

Returns a new default parser

    # File lib/syck.rb, line 91
    def self.parser; Parser.new.set_resolver( self.resolver ); end

quick_emit( oid, opts = {}, &e ) click to toggle source

Allocate an Emitter if needed

    # File lib/syck.rb, line 399
    def self.quick_emit( oid, opts = {}, &e )
        warn "#{caller[0]}: YAML.quick_emit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        out =
            if opts.is_a? Emitter
                opts
            else
                emitter.reset( opts )
            end
        out.emit( oid, &e )
    end

read_type_class( type, obj_class ) click to toggle source

Method to extract colon-separated type and class, returning the type and the constant of the class

    # File lib/syck.rb, line 373
    def self.read_type_class( type, obj_class )
        warn "#{caller[0]}: YAML.read_type_class is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        type, tclass = type.split( ':', 4 ).last(2)
        tclass.split( "::" ).each { |c| obj_class = obj_class.const_get( c ) } if tclass
        return [ type, obj_class ]
    end

resolver() click to toggle source

Returns the default resolver

    # File lib/syck.rb, line 100
    def self.resolver
        warn "#{caller[0]}: YAML.resolver is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        DefaultResolver
    end

tag_class( tag, cls ) click to toggle source

Associates a taguri tag with a Ruby class cls. The taguri is used to give types to classes when loading YAML. Taguris are of the form:

    tag:authorityName,date:specific

The `authorityName` is a domain name or email address. The `date` is the date the type was issued in YYYY or YYYY-MM or YYYY-MM-DD format. The `specific` is a name for the type being added.

For example, built-in YAML types have 'yaml.org' as the `authorityName` and '2002' as the `date`. The `specific` is simply the name of the type:

    tag:yaml.org,2002:int
    tag:yaml.org,2002:float
    tag:yaml.org,2002:timestamp

The domain must be owned by you on the `date` declared. If you don't own any domains on the date you declare the type, you can simply use an e-mail address.

    tag:why@ruby-lang.org,2004:notes/personal

    # File lib/syck/tag.rb, line 34
    def self.tag_class( tag, cls )
        if @@tagged_classes.has_key? tag
            warn "class #{ @@tagged_classes[tag] } held ownership of the #{ tag } tag"
        end
        @@tagged_classes[tag] = cls
    end

tagged_classes() click to toggle source

Returns the complete dictionary of taguris, paired with classes. The key for the dictionary is the full taguri. The value for each key is the class constant associated to that taguri.

    YAML.tagged_classes["tag:yaml.org,2002:int"] => Integer

    # File lib/syck/tag.rb, line 47
    def self.tagged_classes
        @@tagged_classes
    end

tagurize( val ) click to toggle source

Convert a type_id to a taguri

    # File lib/syck.rb, line 348
    def self.tagurize( val )
        warn "#{caller[0]}: YAML.tagurize is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        resolver.tagurize( val )
    end

transfer( type_id, obj ) click to toggle source

Apply a transfer method to a Ruby object

    # File lib/syck.rb, line 356
    def self.transfer( type_id, obj )
        warn "#{caller[0]}: YAML.transfer is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        resolver.transfer( tagurize( type_id ), obj )
    end

try_implicit( obj ) click to toggle source

Apply any implicit a node may qualify for

    # File lib/syck.rb, line 364
    def self.try_implicit( obj )
        warn "#{caller[0]}: YAML.try_implicit is deprecated" if $VERBOSE && !caller[0].start_with?(File.dirname(__FILE__))
        transfer( detect_implicit( obj ), obj )
    end

unescape( value ) click to toggle source

Unescape the condenses escapes

    # File lib/syck/encoding.rb, line 22
    def self.unescape( value )
          warn "#{caller[0]}: YAML.unescape is deprecated" if $VERBOSE
            value.gsub( /\\(?:([nevfbart\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) {
                    if $3
                            ["#$3".hex ].pack('U*')
                    elsif $2
                            [$2].pack( "H2" )
                    else
                            UNESCAPES[$1]
                    end
            }
    end