Module: Syck

Defined in:
lib/syck.rb,
lib/syck/tag.rb,
lib/syck/syck.rb,
lib/syck/error.rb,
lib/syck/types.rb,
lib/syck/ypath.rb,
lib/syck/loader.rb,
lib/syck/stream.rb,
lib/syck/basenode.rb,
lib/syck/encoding.rb,
lib/syck/yamlnode.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

'1.4.0'
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



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

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.



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

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



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

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



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

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



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

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"


125
126
127
128
# File 'lib/syck.rb', line 125

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
      --- []
      --- {}


300
301
302
303
304
305
306
# File 'lib/syck.rb', line 300

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


225
226
227
228
# File 'lib/syck.rb', line 225

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


256
257
258
259
# File 'lib/syck.rb', line 256

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



107
108
109
110
# File 'lib/syck.rb', line 107

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



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

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


141
142
143
# File 'lib/syck.rb', line 141

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


241
242
243
# File 'lib/syck.rb', line 241

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


151
152
153
154
155
# File 'lib/syck.rb', line 151

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.



282
283
284
285
286
287
288
289
# File 'lib/syck.rb', line 282

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



384
385
386
387
388
389
390
391
392
393
394
395
# File 'lib/syck.rb', line 384

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>


184
185
186
# File 'lib/syck.rb', line 184

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


272
273
274
275
# File 'lib/syck.rb', line 272

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


208
209
210
211
212
# File 'lib/syck.rb', line 208

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

.parserObject

Returns a new default parser



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

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

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

Allocate an Emitter if needed



400
401
402
403
404
405
406
407
408
409
# File 'lib/syck.rb', line 400

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-separated type and class, returning the type and the constant of the class



374
375
376
377
378
379
# File 'lib/syck.rb', line 374

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



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

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



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

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



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

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



365
366
367
368
# File 'lib/syck.rb', line 365

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