Module: Syck

Defined in:
lib/syck.rb,
lib/syck/tag.rb,
lib/syck/syck.rb,
lib/syck/ypath.rb,
lib/syck/error.rb,
lib/syck/types.rb,
lib/syck/stream.rb,
lib/syck/loader.rb,
lib/syck/basenode.rb,
lib/syck/yamlnode.rb,
lib/syck/encoding.rb,
lib/syck/constants.rb,
lib/syck/baseemitter.rb

Overview

Constants used throughout the library

Defined Under Namespace

Modules: BaseEmitter, BaseNode Classes: DomainType, Error, Loader, Mapping, Node, Object, Omap, Pairs, ParseError, PrivateType, Sequence, Set, SpecialHash, Stream, TypeError, YPath, YamlNode

Constant Summary collapse

ERROR_NO_HEADER_NODE =

Error messages

"With UseHeader=false, the node Array or Hash must have elements"
ERROR_NEED_HEADER =
"With UseHeader=false, the node must be an Array or Hash"
ERROR_BAD_EXPLICIT =
"Unsupported explicit transfer: '%s'"
ERROR_MANY_EXPLICIT =
"More than one explicit transfer"
ERROR_MANY_IMPLICIT =
"More than one implicit request"
ERROR_NO_ANCHOR =
"No anchor for alias '%s'"
ERROR_BAD_ANCHOR =
"Invalid anchor: %s"
ERROR_MANY_ANCHOR =
"More than one anchor"
ERROR_ANCHOR_ALIAS =
"Can't define both an anchor and an alias"
ERROR_BAD_ALIAS =
"Invalid alias: %s"
ERROR_MANY_ALIAS =
"More than one alias"
ERROR_ZERO_INDENT =
"Can't use zero as an indentation width"
ERROR_UNSUPPORTED_VERSION =
"This release of YAML.rb does not support YAML version %s"
ERROR_UNSUPPORTED_ENCODING =
"Attempt to use unsupported encoding: %s"
VERSION =

Constants

'0.60'
SUPPORTED_YAML_VERSIONS =
['1.0']
WORD_CHAR =

Parser tokens

'A-Za-z0-9'
PRINTABLE_CHAR =
'-_A-Za-z0-9!?/()$\'". '
NOT_PLAIN_CHAR =
'\x7f\x0-\x1f\x80-\x9f'
ESCAPE_CHAR =
'[\\x00-\\x09\\x0b-\\x1f]'
INDICATOR_CHAR =
'*&!|\\\\^@%{}[]='
SPACE_INDICATORS =
'-#:,?'
RESTRICTED_INDICATORS =
'#:,}]'
DNS_COMP_RE =
"\\w(?:[-\\w]*\\w)?"
DNS_NAME_RE =
"(?:(?:#{DNS_COMP_RE}\\.)+#{DNS_COMP_RE}|#{DNS_COMP_RE})"
ESCAPES =
%w{\x00   \x01	\x02	\x03	\x04	\x05	\x06	\a
   \x08	\t		\n		\v		\f		\r		\x0e	\x0f
\x10	\x11	\x12	\x13	\x14	\x15	\x16	\x17
\x18	\x19	\x1a	\e		\x1c	\x1d	\x1e	\x1f
UNESCAPES =
{
				'a' => "\x07", 'b' => "\x08", 't' => "\x09",
				'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
				'r' => "\x0d", 'e' => "\x1b", '\\' => '\\',
}
DEFAULTS =

Default settings

{
	:Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.0',
	:SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false,
	:WidthType => 'absolute', :BestWidth => 80,
	:UseBlock => false, :UseFold => false, :Encoding => :None
}
@@tagged_classes =

A dictionary of taguris which map to Ruby classes.

{}

Class Method Summary collapse

Class Method Details

.add_builtin_type(type_tag, &transfer_proc) ⇒ Object

Add a transfer method for a builtin type


311
312
313
# File 'lib/syck.rb', line 311

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) ⇒ Object

Add a global handler for a YAML domain type.


304
305
306
# File 'lib/syck.rb', line 304

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) ⇒ Object

Add a private document type


326
327
328
329
# File 'lib/syck.rb', line 326

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) ⇒ Object

Add a transfer method for a builtin type


318
319
320
321
# File 'lib/syck.rb', line 318

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) ⇒ Object

Detect typing of a string


334
335
336
337
# File 'lib/syck.rb', line 334

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) ⇒ Object

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"


118
119
120
121
# File 'lib/syck.rb', line 118

def self.dump( obj, io = nil )
    obj.to_yaml( io || io2 = StringIO.new )
    io || ( io2.rewind; io2.read )
end

.dump_stream(*objs) ⇒ Object

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

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

      --- []
      --- {}

293
294
295
296
297
298
299
# File 'lib/syck.rb', line 293

def self.dump_stream( *objs )
    d = Stream.new
    objs.each do |doc|
        d.add( doc )
    end
    d.emit
end

.each_document(io, &block) ⇒ Object

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

218
219
220
221
# File 'lib/syck.rb', line 218

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) ⇒ Object

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

249
250
251
252
# File 'lib/syck.rb', line 249

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

.emitterObject

Returns a new default emitter


100
101
102
103
# File 'lib/syck.rb', line 100

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 = "") ⇒ Object

Escape the string, condensing common escapes


10
11
12
13
14
15
16
17
# 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_parserObject

Returns a new generic parser


88
89
90
91
# File 'lib/syck.rb', line 88

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) ⇒ Object

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


134
135
136
# File 'lib/syck.rb', line 134

def self.load( io )
    parser.load( io )
end

.load_documents(io, &doc_proc) ⇒ Object

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

234
235
236
# File 'lib/syck.rb', line 234

def self.load_documents( io, &doc_proc )
    parser.load_documents( io, &doc_proc )
end

.load_file(filepath) ⇒ Object

Load a document from the file located at filepath.

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


144
145
146
147
148
# File 'lib/syck.rb', line 144

def self.load_file( filepath )
    File.open( filepath ) do |f|
        load( f )
    end
end

.load_stream(io) ⇒ Object

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


275
276
277
278
279
280
281
282
# File 'lib/syck.rb', line 275

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

.object_maker(obj_class, val) ⇒ Object

Allocate blank object


377
378
379
380
381
382
383
384
385
386
387
388
# File 'lib/syck.rb', line 377

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) ⇒ Object

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>

177
178
179
# File 'lib/syck.rb', line 177

def self.parse( io )
    generic_parser.load( io )
end

.parse_documents(io, &doc_proc) ⇒ Object

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

265
266
267
268
# File 'lib/syck.rb', line 265

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) ⇒ Object

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

201
202
203
204
205
# File 'lib/syck.rb', line 201

def self.parse_file( filepath )
    File.open( filepath ) do |f|
        parse( f )
    end
end

.parserObject

Returns a new default parser


85
# File 'lib/syck.rb', line 85

def self.parser; Parser.new.set_resolver( self.resolver ); end

.quick_emit(oid, opts = {}, &e) ⇒ Object

Allocate an Emitter if needed


393
394
395
396
397
398
399
400
401
402
# File 'lib/syck.rb', line 393

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) ⇒ Object

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


367
368
369
370
371
372
# File 'lib/syck.rb', line 367

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

.resolverObject

Returns the default resolver


94
95
96
97
# File 'lib/syck.rb', line 94

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) ⇒ Object

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:[email protected],2004:notes/personal

35
36
37
38
39
40
# File 'lib/syck/tag.rb', line 35

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_classesObject

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

48
49
50
# File 'lib/syck/tag.rb', line 48

def self.tagged_classes
    @@tagged_classes
end

.tagurize(val) ⇒ Object

Convert a type_id to a taguri


342
343
344
345
# File 'lib/syck.rb', line 342

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) ⇒ Object

Apply a transfer method to a Ruby object


350
351
352
353
# File 'lib/syck.rb', line 350

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) ⇒ Object

Apply any implicit a node may qualify for


358
359
360
361
# File 'lib/syck.rb', line 358

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) ⇒ Object

Unescape the condenses escapes


22
23
24
25
26
27
28
29
30
31
32
33
# 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