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).
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).
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
Constants used throughout the library
Same interface as DBM class
Handle Unicode-to-Internal conversion
Error messages and exception class
YAML::Loader class .. type handling ..
$Id: tag.rb 26819 2010-03-04 19:01:52Z wyhaines $
why the lucky stiff
Classes required by the full core typeset
Default settings
Error messages
Constants
Parser tokens
Add a transfer method for a builtin type
# File yaml.rb, line 305 def YAML.add_builtin_type( type_tag, &transfer_proc ) resolver.add_type( "tag:yaml.org,2002:#{ type_tag }", transfer_proc ) end
Add a global handler for a YAML domain type.
# File yaml.rb, line 298 def YAML.add_domain_type( domain, type_tag, &transfer_proc ) resolver.add_type( "tag:#{ domain }:#{ type_tag }", transfer_proc ) end
Add a private document type
# File yaml.rb, line 319 def YAML.add_private_type( type_re, &transfer_proc ) resolver.add_type( "x-private:" + type_re, transfer_proc ) end
Add a transfer method for a builtin type
# File yaml.rb, line 312 def YAML.add_ruby_type( type_tag, &transfer_proc ) resolver.add_type( "tag:ruby.yaml.org,2002:#{ type_tag }", transfer_proc ) end
Detect typing of a string
# File yaml.rb, line 326 def YAML.detect_implicit( val ) resolver.detect_implicit( val ) end
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 yaml.rb, line 115 def YAML.dump( obj, io = nil ) obj.to_yaml( io || io2 = StringIO.new ) io || ( io2.rewind; io2.read ) end
Returns a YAML stream containing each of the items
in objs
, each having their own document.
YAML.dump_stream( 0, [], {} ) #=> --- 0 --- [] --- {}
# File yaml.rb, line 287 def YAML.dump_stream( *objs ) d = YAML::Stream.new objs.each do |doc| d.add( doc ) end d.emit end
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 yaml.rb, line 215 def YAML.each_document( io, &block ) yp = parser.load_documents( io, &block ) end
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 yaml.rb, line 245 def YAML.each_node( io, &doc_proc ) yp = generic_parser.load_documents( io, &doc_proc ) end
Returns a new default emitter
# File yaml.rb, line 100 def YAML.emitter; Emitter.new.set_resolver( YAML.resolver ); end
Escape the string, condensing common escapes
# File yaml/encoding.rb, line 10 def YAML.escape( value, skip = "" ) value.gsub( /\\/, "\\\\\\" ). gsub( /"/, "\\\"" ). gsub( /([\x00-\x1f])/ ) do |x| skip[x] || ESCAPES[ x.unpack("C")[0] ] end end
Returns a new generic parser
# File yaml.rb, line 96 def YAML.generic_parser; Parser.new.set_resolver( GenericResolver ); end
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 yaml.rb, line 131 def YAML.load( io ) yp = parser.load( io ) end
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 yaml.rb, line 230 def YAML.load_documents( io, &doc_proc ) YAML.each_document( io, &doc_proc ) end
Load a document from the file located at filepath.
YAML.load_file( 'animals.yaml' ) #=> ['badger', 'elephant', 'tiger']
# File yaml.rb, line 141 def YAML.load_file( filepath ) File.open( filepath ) do |f| load( f ) end end
Loads all documents from the current io stream, returning a
YAML::Stream
object containing all loaded documents.
# File yaml.rb, line 269 def YAML.load_stream( io ) d = nil parser.load_documents( io ) do |doc| d = YAML::Stream.new if not d d.add( doc ) end return d end
Class method for creating streams
# File yaml/stringio.rb, line 55 def YAML.make_stream( io ) if String === io io = StringIO.new( io ) elsif not IO === io raise YAML::Error, "YAML stream must be an IO or String object." end if YAML::unicode def io.readline YAML.utf_to_internal( readline( @ln_sep ), @utf_encoding ) end def io.check_unicode @utf_encoding = YAML.sniff_encoding( read( 4 ) ) @ln_sep = YAML.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
Allocate blank object
# File yaml.rb, line 364 def YAML.object_maker( obj_class, val ) if Hash === val o = obj_class.allocate val.each_pair { |k,v| o.instance_variable_set("@#{k}", v) } o else raise YAML::Error, "Invalid object explicitly tagged !ruby/Object: " + val.inspect end end
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 yaml.rb, line 174 def YAML.parse( io ) yp = generic_parser.load( io ) end
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 yaml.rb, line 260 def YAML.parse_documents( io, &doc_proc ) YAML.each_node( io, &doc_proc ) end
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 yaml.rb, line 198 def YAML.parse_file( filepath ) File.open( filepath ) do |f| parse( f ) end end
Returns a new default parser
# File yaml.rb, line 94 def YAML.parser; Parser.new.set_resolver( YAML.resolver ); end
Allocate an Emitter if needed
# File yaml.rb, line 379 def YAML.quick_emit( oid, opts = {}, &e ) out = if opts.is_a? YAML::Emitter opts else emitter.reset( opts ) end oid = case oid when Fixnum, NilClass; oid else oid = "#{oid.object_id}-#{oid.hash}" end out.emit( oid, &e ) end
Method to extract colon-seperated type and class, returning the type and the constant of the class
# File yaml.rb, line 355 def YAML.read_type_class( type, obj_class ) scheme, domain, type, tclass = type.split( ':', 4 ) tclass.split( "::" ).each { |c| obj_class = obj_class.const_get( c ) } if tclass return [ type, obj_class ] end
Returns the default resolver
# File yaml.rb, line 98 def YAML.resolver; DefaultResolver; end
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 yaml/tag.rb, line 34 def YAML.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
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 yaml/tag.rb, line 47 def YAML.tagged_classes @@tagged_classes end
Convert a type_id to a taguri
# File yaml.rb, line 333 def YAML.tagurize( val ) resolver.tagurize( val ) end
Apply a transfer method to a Ruby object
# File yaml.rb, line 340 def YAML.transfer( type_id, obj ) resolver.transfer( YAML.tagurize( type_id ), obj ) end