syck 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. data/.autotest.erb +8 -0
  2. data/.gemtest +0 -0
  3. data/CHANGELOG.rdoc +6 -0
  4. data/Manifest.txt +52 -0
  5. data/README.rdoc +51 -0
  6. data/Rakefile +32 -0
  7. data/ext/syck/bytecode.c +1165 -0
  8. data/ext/syck/emitter.c +1247 -0
  9. data/ext/syck/extconf.h +3 -0
  10. data/ext/syck/extconf.rb +5 -0
  11. data/ext/syck/gram.c +1894 -0
  12. data/ext/syck/gram.h +79 -0
  13. data/ext/syck/handler.c +173 -0
  14. data/ext/syck/implicit.c +2990 -0
  15. data/ext/syck/node.c +407 -0
  16. data/ext/syck/rubyext.c +2328 -0
  17. data/ext/syck/syck.c +524 -0
  18. data/ext/syck/syck.h +453 -0
  19. data/ext/syck/token.c +2724 -0
  20. data/ext/syck/yaml2byte.c +259 -0
  21. data/ext/syck/yamlbyte.h +171 -0
  22. data/lib/syck.bundle +0 -0
  23. data/lib/syck.rb +447 -0
  24. data/lib/syck/baseemitter.rb +242 -0
  25. data/lib/syck/basenode.rb +222 -0
  26. data/lib/syck/constants.rb +45 -0
  27. data/lib/syck/encoding.rb +35 -0
  28. data/lib/syck/error.rb +34 -0
  29. data/lib/syck/loader.rb +14 -0
  30. data/lib/syck/rubytypes.rb +450 -0
  31. data/lib/syck/stream.rb +41 -0
  32. data/lib/syck/stringio.rb +85 -0
  33. data/lib/syck/syck.rb +16 -0
  34. data/lib/syck/tag.rb +95 -0
  35. data/lib/syck/types.rb +192 -0
  36. data/lib/syck/yamlnode.rb +54 -0
  37. data/lib/syck/ypath.rb +54 -0
  38. data/lib/yaml/syck.rb +14 -0
  39. data/test/helper.rb +2 -0
  40. data/test/test_array.rb +13 -0
  41. data/test/test_boolean.rb +36 -0
  42. data/test/test_class.rb +11 -0
  43. data/test/test_exception.rb +45 -0
  44. data/test/test_hash.rb +24 -0
  45. data/test/test_null.rb +19 -0
  46. data/test/test_omap.rb +55 -0
  47. data/test/test_set.rb +30 -0
  48. data/test/test_string.rb +44 -0
  49. data/test/test_struct.rb +32 -0
  50. data/test/test_symbol.rb +21 -0
  51. data/test/test_time.rb +23 -0
  52. data/test/test_yaml.rb +1403 -0
  53. data/test/test_yaml_properties.rb +63 -0
  54. metadata +187 -0
@@ -0,0 +1,45 @@
1
+ #
2
+ # Constants used throughout the library
3
+ #
4
+ module Syck
5
+
6
+ #
7
+ # Constants
8
+ #
9
+ VERSION = '1.0.0'
10
+ SUPPORTED_YAML_VERSIONS = ['1.0']
11
+
12
+ #
13
+ # Parser tokens
14
+ #
15
+ WORD_CHAR = 'A-Za-z0-9'
16
+ PRINTABLE_CHAR = '-_A-Za-z0-9!?/()$\'". '
17
+ NOT_PLAIN_CHAR = '\x7f\x0-\x1f\x80-\x9f'
18
+ ESCAPE_CHAR = '[\\x00-\\x09\\x0b-\\x1f]'
19
+ INDICATOR_CHAR = '*&!|\\\\^@%{}[]='
20
+ SPACE_INDICATORS = '-#:,?'
21
+ RESTRICTED_INDICATORS = '#:,}]'
22
+ DNS_COMP_RE = "\\w(?:[-\\w]*\\w)?"
23
+ DNS_NAME_RE = "(?:(?:#{DNS_COMP_RE}\\.)+#{DNS_COMP_RE}|#{DNS_COMP_RE})"
24
+ ESCAPES = %w{\x00 \x01 \x02 \x03 \x04 \x05 \x06 \a
25
+ \x08 \t \n \v \f \r \x0e \x0f
26
+ \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17
27
+ \x18 \x19 \x1a \e \x1c \x1d \x1e \x1f
28
+ }
29
+ UNESCAPES = {
30
+ 'a' => "\x07", 'b' => "\x08", 't' => "\x09",
31
+ 'n' => "\x0a", 'v' => "\x0b", 'f' => "\x0c",
32
+ 'r' => "\x0d", 'e' => "\x1b", '\\' => '\\',
33
+ }
34
+
35
+ #
36
+ # Default settings
37
+ #
38
+ DEFAULTS = {
39
+ :Indent => 2, :UseHeader => false, :UseVersion => false, :Version => '1.0',
40
+ :SortKeys => false, :AnchorFormat => 'id%03d', :ExplicitTypes => false,
41
+ :WidthType => 'absolute', :BestWidth => 80,
42
+ :UseBlock => false, :UseFold => false, :Encoding => :None
43
+ }
44
+
45
+ end
@@ -0,0 +1,35 @@
1
+ #
2
+ # Handle Unicode-to-Internal conversion
3
+ #
4
+
5
+ module Syck
6
+
7
+ #
8
+ # Escape the string, condensing common escapes
9
+ #
10
+ def self.escape( value, skip = "" )
11
+ warn "#{caller[0]}: YAML.escape is deprecated" if $VERBOSE
12
+ value.gsub( /\\/, "\\\\\\" ).
13
+ gsub( /"/, "\\\"" ).
14
+ gsub( /([\x00-\x1f])/ ) do
15
+ skip[$&] || ESCAPES[ $&.unpack("C")[0] ]
16
+ end
17
+ end
18
+
19
+ #
20
+ # Unescape the condenses escapes
21
+ #
22
+ def self.unescape( value )
23
+ warn "#{caller[0]}: YAML.unescape is deprecated" if $VERBOSE
24
+ value.gsub( /\\(?:([nevfbart\\])|0?x([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/ ) {
25
+ if $3
26
+ ["#$3".hex ].pack('U*')
27
+ elsif $2
28
+ [$2].pack( "H2" )
29
+ else
30
+ UNESCAPES[$1]
31
+ end
32
+ }
33
+ end
34
+
35
+ end
@@ -0,0 +1,34 @@
1
+ #
2
+ # Error messages and exception class
3
+ #
4
+
5
+ module Syck
6
+
7
+ #
8
+ # Error messages
9
+ #
10
+
11
+ ERROR_NO_HEADER_NODE = "With UseHeader=false, the node Array or Hash must have elements"
12
+ ERROR_NEED_HEADER = "With UseHeader=false, the node must be an Array or Hash"
13
+ ERROR_BAD_EXPLICIT = "Unsupported explicit transfer: '%s'"
14
+ ERROR_MANY_EXPLICIT = "More than one explicit transfer"
15
+ ERROR_MANY_IMPLICIT = "More than one implicit request"
16
+ ERROR_NO_ANCHOR = "No anchor for alias '%s'"
17
+ ERROR_BAD_ANCHOR = "Invalid anchor: %s"
18
+ ERROR_MANY_ANCHOR = "More than one anchor"
19
+ ERROR_ANCHOR_ALIAS = "Can't define both an anchor and an alias"
20
+ ERROR_BAD_ALIAS = "Invalid alias: %s"
21
+ ERROR_MANY_ALIAS = "More than one alias"
22
+ ERROR_ZERO_INDENT = "Can't use zero as an indentation width"
23
+ ERROR_UNSUPPORTED_VERSION = "This release of YAML.rb does not support YAML version %s"
24
+ ERROR_UNSUPPORTED_ENCODING = "Attempt to use unsupported encoding: %s"
25
+
26
+ #
27
+ # YAML Error classes
28
+ #
29
+
30
+ class Error < StandardError; end
31
+ class ParseError < Error; end
32
+ class TypeError < StandardError; end
33
+
34
+ end
@@ -0,0 +1,14 @@
1
+ #
2
+ # YAML::Loader class
3
+ # .. type handling ..
4
+ #
5
+ module Syck
6
+ class Loader
7
+ TRANSFER_DOMAINS = {
8
+ 'yaml.org,2002' => {},
9
+ 'ruby.yaml.org,2002' => {}
10
+ }
11
+ PRIVATE_TYPES = {}
12
+ IMPLICIT_TYPES = [ 'null', 'bool', 'time', 'int', 'float' ]
13
+ end
14
+ end
@@ -0,0 +1,450 @@
1
+ # -*- mode: ruby; ruby-indent-level: 4; tab-width: 4 -*- vim: sw=4 ts=4
2
+ require 'date'
3
+
4
+ class Class
5
+ def to_yaml( opts = {} )
6
+ raise TypeError, "can't dump anonymous class %s" % self.class
7
+ end
8
+ end
9
+
10
+ class Object
11
+ yaml_as "tag:ruby.yaml.org,2002:object"
12
+ def to_yaml_style; end
13
+ undef to_yaml_properties rescue nil
14
+ def to_yaml_properties; instance_variables.sort; end
15
+ def to_yaml( opts = {} )
16
+ Syck::quick_emit( self, opts ) do |out|
17
+ out.map( taguri, to_yaml_style ) do |map|
18
+ to_yaml_properties.each do |m|
19
+ map.add( m[1..-1], instance_variable_get( m ) )
20
+ end
21
+ end
22
+ end
23
+ end
24
+ alias :syck_to_yaml :to_yaml
25
+ end
26
+
27
+ class Hash
28
+ yaml_as "tag:ruby.yaml.org,2002:hash"
29
+ yaml_as "tag:yaml.org,2002:map"
30
+ def yaml_initialize( tag, val )
31
+ if Array === val
32
+ update Hash.[]( *val ) # Convert the map to a sequence
33
+ elsif Hash === val
34
+ update val
35
+ else
36
+ raise Syck::TypeError, "Invalid map explicitly tagged #{ tag }: " + val.inspect
37
+ end
38
+ end
39
+ def to_yaml( opts = {} )
40
+ Syck::quick_emit( self, opts ) do |out|
41
+ out.map( taguri, to_yaml_style ) do |map|
42
+ each do |k, v|
43
+ map.add( k, v )
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+
50
+ class Struct
51
+ yaml_as "tag:ruby.yaml.org,2002:struct"
52
+ def self.yaml_tag_class_name; self.name.gsub( "Struct::", "" ); end
53
+ def self.yaml_tag_read_class( name ); "Struct::#{ name }"; end
54
+ def self.yaml_new( klass, tag, val )
55
+ if Hash === val
56
+ struct_type = nil
57
+
58
+ #
59
+ # Use existing Struct if it exists
60
+ #
61
+ props = {}
62
+ val.delete_if { |k,v| props[k] = v if k =~ /^@/ }
63
+ begin
64
+ struct_type = Syck.read_type_class( tag, Struct ).last
65
+ rescue NameError
66
+ end
67
+ if not struct_type
68
+ struct_def = [ tag.split( ':', 4 ).last ]
69
+ struct_type = Struct.new( *struct_def.concat( val.keys.collect { |k| k.intern } ) )
70
+ end
71
+
72
+ #
73
+ # Set the Struct properties
74
+ #
75
+ st = Syck::object_maker( struct_type, {} )
76
+ st.members.each do |m|
77
+ st.send( "#{m}=", val[m.to_s] )
78
+ end
79
+ props.each do |k,v|
80
+ st.instance_variable_set(k, v)
81
+ end
82
+ st
83
+ else
84
+ raise Syck::TypeError, "Invalid Ruby Struct: " + val.inspect
85
+ end
86
+ end
87
+ def to_yaml( opts = {} )
88
+ Syck::quick_emit( self, opts ) do |out|
89
+ #
90
+ # Basic struct is passed as a YAML map
91
+ #
92
+ out.map( taguri, to_yaml_style ) do |map|
93
+ self.members.each do |m|
94
+ map.add( m.to_s, self[m.to_s] )
95
+ end
96
+ self.to_yaml_properties.each do |m|
97
+ map.add( m, instance_variable_get( m ) )
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+
104
+ class Array
105
+ yaml_as "tag:ruby.yaml.org,2002:array"
106
+ yaml_as "tag:yaml.org,2002:seq"
107
+ def yaml_initialize( tag, val ); concat( val.to_a ); end
108
+ def to_yaml( opts = {} )
109
+ Syck::quick_emit( self, opts ) do |out|
110
+ out.seq( taguri, to_yaml_style ) do |seq|
111
+ each do |x|
112
+ seq.add( x )
113
+ end
114
+ end
115
+ end
116
+ end
117
+ end
118
+
119
+ class Exception
120
+ yaml_as "tag:ruby.yaml.org,2002:exception"
121
+ def Exception.yaml_new( klass, tag, val )
122
+ o = klass.allocate
123
+ Exception.instance_method(:initialize).bind(o).call(val.delete('message'))
124
+ val.each_pair do |k,v|
125
+ o.instance_variable_set("@#{k}", v)
126
+ end
127
+ o
128
+ end
129
+ def to_yaml( opts = {} )
130
+ Syck::quick_emit( self, opts ) do |out|
131
+ out.map( taguri, to_yaml_style ) do |map|
132
+ map.add( 'message', message )
133
+ to_yaml_properties.each do |m|
134
+ map.add( m[1..-1], instance_variable_get( m ) )
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+
141
+ class String
142
+ yaml_as "tag:ruby.yaml.org,2002:string"
143
+ yaml_as "tag:yaml.org,2002:binary"
144
+ yaml_as "tag:yaml.org,2002:str"
145
+ def is_complex_yaml?
146
+ to_yaml_style or not to_yaml_properties.empty? or self =~ /\n.+/
147
+ end
148
+ def is_binary_data?
149
+ self.count("\x00-\x7F", "^ -~\t\r\n").fdiv(self.size) > 0.3 || self.index("\x00") unless self.empty?
150
+ end
151
+ def String.yaml_new( klass, tag, val )
152
+ val = val.unpack("m")[0] if tag == "tag:yaml.org,2002:binary"
153
+ val = { 'str' => val } if String === val
154
+ if Hash === val
155
+ s = klass.allocate
156
+ # Thank you, NaHi
157
+ String.instance_method(:initialize).
158
+ bind(s).
159
+ call( val.delete( 'str' ) )
160
+ val.each { |k,v| s.instance_variable_set( k, v ) }
161
+ s
162
+ else
163
+ raise Syck::TypeError, "Invalid String: " + val.inspect
164
+ end
165
+ end
166
+ def to_yaml( opts = {} )
167
+ Syck::quick_emit( is_complex_yaml? ? self : nil, opts ) do |out|
168
+ if is_binary_data?
169
+ out.scalar( "tag:yaml.org,2002:binary", [self].pack("m"), :literal )
170
+ elsif to_yaml_properties.empty?
171
+ out.scalar( taguri, self, self =~ /^:/ ? :quote2 : to_yaml_style )
172
+ else
173
+ out.map( taguri, to_yaml_style ) do |map|
174
+ map.add( 'str', "#{self}" )
175
+ to_yaml_properties.each do |m|
176
+ map.add( m, instance_variable_get( m ) )
177
+ end
178
+ end
179
+ end
180
+ end
181
+ end
182
+ end
183
+
184
+ class Symbol
185
+ yaml_as "tag:ruby.yaml.org,2002:symbol"
186
+ yaml_as "tag:ruby.yaml.org,2002:sym"
187
+ def Symbol.yaml_new( klass, tag, val )
188
+ if String === val
189
+ val = Syck::load( val ) if val =~ /\A(["']).*\1\z/
190
+ val.intern
191
+ else
192
+ raise Syck::TypeError, "Invalid Symbol: " + val.inspect
193
+ end
194
+ end
195
+ def to_yaml( opts = {} )
196
+ Syck::quick_emit( nil, opts ) do |out|
197
+ out.scalar( "tag:yaml.org,2002:str", self.inspect, :plain )
198
+ end
199
+ end
200
+ end
201
+
202
+ class Range
203
+ yaml_as "tag:ruby.yaml.org,2002:range"
204
+ def Range.yaml_new( klass, tag, val )
205
+ inr = %r'(\w+|[+-]?\d+(?:\.\d+)?(?:e[+-]\d+)?|"(?:[^\\"]|\\.)*")'
206
+ opts = {}
207
+ if String === val and val =~ /^#{inr}(\.{2,3})#{inr}$/o
208
+ r1, rdots, r2 = $1, $2, $3
209
+ opts = {
210
+ 'begin' => Syck.load( "--- #{r1}" ),
211
+ 'end' => Syck.load( "--- #{r2}" ),
212
+ 'excl' => rdots.length == 3
213
+ }
214
+ val = {}
215
+ elsif Hash === val
216
+ opts['begin'] = val.delete('begin')
217
+ opts['end'] = val.delete('end')
218
+ opts['excl'] = val.delete('excl')
219
+ end
220
+ if Hash === opts
221
+ r = Syck::object_maker( klass, {} )
222
+ # Thank you, NaHi
223
+ Range.instance_method(:initialize).
224
+ bind(r).
225
+ call( opts['begin'], opts['end'], opts['excl'] )
226
+ val.each { |k,v| r.instance_variable_set( k, v ) }
227
+ r
228
+ else
229
+ raise Syck::TypeError, "Invalid Range: " + val.inspect
230
+ end
231
+ end
232
+ def to_yaml( opts = {} )
233
+ Syck::quick_emit( self, opts ) do |out|
234
+ # if self.begin.is_complex_yaml? or self.begin.respond_to? :to_str or
235
+ # self.end.is_complex_yaml? or self.end.respond_to? :to_str or
236
+ # not to_yaml_properties.empty?
237
+ out.map( taguri, to_yaml_style ) do |map|
238
+ map.add( 'begin', self.begin )
239
+ map.add( 'end', self.end )
240
+ map.add( 'excl', self.exclude_end? )
241
+ to_yaml_properties.each do |m|
242
+ map.add( m, instance_variable_get( m ) )
243
+ end
244
+ end
245
+ # else
246
+ # out.scalar( taguri ) do |sc|
247
+ # sc.embed( self.begin )
248
+ # sc.concat( self.exclude_end? ? "..." : ".." )
249
+ # sc.embed( self.end )
250
+ # end
251
+ # end
252
+ end
253
+ end
254
+ end
255
+
256
+ class Regexp
257
+ yaml_as "tag:ruby.yaml.org,2002:regexp"
258
+ def Regexp.yaml_new( klass, tag, val )
259
+ if String === val and val =~ /^\/(.*)\/([mixn]*)$/
260
+ val = { 'regexp' => $1, 'mods' => $2 }
261
+ end
262
+ if Hash === val
263
+ mods = nil
264
+ unless val['mods'].to_s.empty?
265
+ mods = 0x00
266
+ mods |= Regexp::EXTENDED if val['mods'].include?( 'x' )
267
+ mods |= Regexp::IGNORECASE if val['mods'].include?( 'i' )
268
+ mods |= Regexp::MULTILINE if val['mods'].include?( 'm' )
269
+ mods |= Regexp::NOENCODING if val['mods'].include?( 'n' )
270
+ end
271
+ val.delete( 'mods' )
272
+ r = Syck::object_maker( klass, {} )
273
+ Regexp.instance_method(:initialize).
274
+ bind(r).
275
+ call( val.delete( 'regexp' ), mods )
276
+ val.each { |k,v| r.instance_variable_set( k, v ) }
277
+ r
278
+ else
279
+ raise Syck::TypeError, "Invalid Regular expression: " + val.inspect
280
+ end
281
+ end
282
+ def to_yaml( opts = {} )
283
+ Syck::quick_emit( nil, opts ) do |out|
284
+ if to_yaml_properties.empty?
285
+ out.scalar( taguri, self.inspect, :plain )
286
+ else
287
+ out.map( taguri, to_yaml_style ) do |map|
288
+ src = self.inspect
289
+ if src =~ /\A\/(.*)\/([a-z]*)\Z/
290
+ map.add( 'regexp', $1 )
291
+ map.add( 'mods', $2 )
292
+ else
293
+ raise Syck::TypeError, "Invalid Regular expression: " + src
294
+ end
295
+ to_yaml_properties.each do |m|
296
+ map.add( m, instance_variable_get( m ) )
297
+ end
298
+ end
299
+ end
300
+ end
301
+ end
302
+ end
303
+
304
+ class Time
305
+ yaml_as "tag:ruby.yaml.org,2002:time"
306
+ yaml_as "tag:yaml.org,2002:timestamp"
307
+ def Time.yaml_new( klass, tag, val )
308
+ if Hash === val
309
+ t = val.delete( 'at' )
310
+ val.each { |k,v| t.instance_variable_set( k, v ) }
311
+ t
312
+ else
313
+ raise Syck::TypeError, "Invalid Time: " + val.inspect
314
+ end
315
+ end
316
+ def to_yaml( opts = {} )
317
+ Syck::quick_emit( self, opts ) do |out|
318
+ tz = "Z"
319
+ # from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
320
+ unless self.utc?
321
+ utc_same_instant = self.dup.utc
322
+ utc_same_writing = Time.utc(year,month,day,hour,min,sec,usec)
323
+ difference_to_utc = utc_same_writing - utc_same_instant
324
+ if (difference_to_utc < 0)
325
+ difference_sign = '-'
326
+ absolute_difference = -difference_to_utc
327
+ else
328
+ difference_sign = '+'
329
+ absolute_difference = difference_to_utc
330
+ end
331
+ difference_minutes = (absolute_difference/60).round
332
+ tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
333
+ end
334
+ standard = self.strftime( "%Y-%m-%d %H:%M:%S" )
335
+ standard += ".%06d" % [usec] if usec.nonzero?
336
+ standard += " %s" % [tz]
337
+ if to_yaml_properties.empty?
338
+ out.scalar( taguri, standard, :plain )
339
+ else
340
+ out.map( taguri, to_yaml_style ) do |map|
341
+ map.add( 'at', standard )
342
+ to_yaml_properties.each do |m|
343
+ map.add( m, instance_variable_get( m ) )
344
+ end
345
+ end
346
+ end
347
+ end
348
+ end
349
+ end
350
+
351
+ class Date
352
+ yaml_as "tag:yaml.org,2002:timestamp#ymd"
353
+ def to_yaml( opts = {} )
354
+ Syck::quick_emit( self, opts ) do |out|
355
+ out.scalar( "tag:yaml.org,2002:timestamp", self.to_s, :plain )
356
+ end
357
+ end
358
+ end
359
+
360
+ class Integer
361
+ yaml_as "tag:yaml.org,2002:int"
362
+ def to_yaml( opts = {} )
363
+ Syck::quick_emit( nil, opts ) do |out|
364
+ out.scalar( "tag:yaml.org,2002:int", self.to_s, :plain )
365
+ end
366
+ end
367
+ end
368
+
369
+ class Float
370
+ yaml_as "tag:yaml.org,2002:float"
371
+ def to_yaml( opts = {} )
372
+ Syck::quick_emit( nil, opts ) do |out|
373
+ str = self.to_s
374
+ if str == "Infinity"
375
+ str = ".Inf"
376
+ elsif str == "-Infinity"
377
+ str = "-.Inf"
378
+ elsif str == "NaN"
379
+ str = ".NaN"
380
+ end
381
+ out.scalar( "tag:yaml.org,2002:float", str, :plain )
382
+ end
383
+ end
384
+ end
385
+
386
+ class Rational
387
+ yaml_as "tag:ruby.yaml.org,2002:object:Rational"
388
+ def Rational.yaml_new( klass, tag, val )
389
+ if val.is_a? String
390
+ Rational( val )
391
+ else
392
+ Rational( val['numerator'], val['denominator'] )
393
+ end
394
+ end
395
+ def to_yaml( opts = {} )
396
+ Syck::quick_emit( self, opts ) do |out|
397
+ out.map( taguri, nil ) do |map|
398
+ map.add( 'denominator', denominator )
399
+ map.add( 'numerator', numerator )
400
+ end
401
+ end
402
+ end
403
+ end
404
+
405
+ class Complex
406
+ yaml_as "tag:ruby.yaml.org,2002:object:Complex"
407
+ def Complex.yaml_new( klass, tag, val )
408
+ if val.is_a? String
409
+ Complex( val )
410
+ else
411
+ Complex( val['real'], val['image'] )
412
+ end
413
+ end
414
+ def to_yaml( opts = {} )
415
+ Syck::quick_emit( self, opts ) do |out|
416
+ out.map( taguri, nil ) do |map|
417
+ map.add( 'image', imaginary )
418
+ map.add( 'real', real )
419
+ end
420
+ end
421
+ end
422
+ end
423
+
424
+ class TrueClass
425
+ yaml_as "tag:yaml.org,2002:bool#yes"
426
+ def to_yaml( opts = {} )
427
+ Syck::quick_emit( nil, opts ) do |out|
428
+ out.scalar( taguri, "true", :plain )
429
+ end
430
+ end
431
+ end
432
+
433
+ class FalseClass
434
+ yaml_as "tag:yaml.org,2002:bool#no"
435
+ def to_yaml( opts = {} )
436
+ Syck::quick_emit( nil, opts ) do |out|
437
+ out.scalar( taguri, "false", :plain )
438
+ end
439
+ end
440
+ end
441
+
442
+ class NilClass
443
+ yaml_as "tag:yaml.org,2002:null"
444
+ def to_yaml( opts = {} )
445
+ Syck::quick_emit( nil, opts ) do |out|
446
+ out.scalar( taguri, "", :plain )
447
+ end
448
+ end
449
+ end
450
+