RbYAML 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/rbyaml.rb +14 -256
- data/lib/rbyaml.rb.~1.2.~ +383 -0
- data/lib/rbyaml/composer.rb +9 -11
- data/lib/rbyaml/{composer.rb.~1.2.~ → composer.rb.~1.3.~} +28 -25
- data/lib/rbyaml/constants.rb +95 -0
- data/lib/rbyaml/constructor.rb +180 -89
- data/lib/rbyaml/{constructor.rb.~1.2.~ → constructor.rb.~1.9.~} +137 -95
- data/lib/rbyaml/dumper.rb +12 -9
- data/lib/rbyaml/dumper.rb.~1.3.~ +36 -0
- data/lib/rbyaml/emitter.rb +14 -28
- data/lib/rbyaml/{emitter.rb.~1.2.~ → emitter.rb.~1.6.~} +22 -33
- data/lib/rbyaml/error.rb +4 -57
- data/lib/rbyaml/error.rb.~1.2.~ +75 -0
- data/lib/rbyaml/events.rb +8 -14
- data/lib/rbyaml/{events.rb.~1.2.~ → events.rb.~1.4.~} +29 -6
- data/lib/rbyaml/nodes.rb +5 -5
- data/lib/rbyaml/{nodes.rb.~1.2.~ → nodes.rb.~1.3.~} +13 -9
- data/lib/rbyaml/parser.rb +70 -108
- data/lib/rbyaml/parser.rb.~1.4.~ +632 -0
- data/lib/rbyaml/representer.rb +19 -157
- data/lib/rbyaml/representer.rb.old +317 -0
- data/lib/rbyaml/{representer.rb.~1.2.~ → representer.rb.~1.5.~} +60 -26
- data/lib/rbyaml/resolver.rb +6 -6
- data/lib/rbyaml/{resolver.rb.~1.1.~ → resolver.rb.~1.6.~} +20 -20
- data/lib/rbyaml/rubytypes.rb +391 -0
- data/lib/rbyaml/scanner.rb +123 -225
- data/lib/rbyaml/{scanner.rb.~1.2.~ → scanner.rb.~1.5.~} +466 -378
- data/lib/rbyaml/serializer.rb +9 -9
- data/lib/rbyaml/{serializer.rb.~1.2.~ → serializer.rb.~1.4.~} +19 -17
- data/lib/rbyaml/stream.rb +48 -0
- data/lib/rbyaml/tag.rb +72 -0
- data/lib/rbyaml/tokens.rb +22 -16
- data/lib/rbyaml/{tokens.rb.~1.2.~ → tokens.rb.~1.3.~} +44 -4
- data/lib/rbyaml/types.rb +146 -0
- data/lib/rbyaml/util.rb.~1.3.~ +38 -0
- data/lib/rbyaml/yaml.rb +22 -32
- data/lib/rbyaml/{yaml.rb.~1.2.~ → yaml.rb.~1.5.~} +17 -17
- data/test/load_one.rb +6 -0
- data/test/load_one_yaml.rb +6 -0
- data/test/output_events.rb +9 -0
- data/test/test_add_ctor.rb +51 -0
- data/test/test_add_ctor.rb.~1.1.~ +30 -0
- data/test/test_bm.rb +2 -2
- data/test/test_bm.rb.~1.1.~ +28 -0
- data/test/test_gems.rb +10 -0
- data/test/test_one.rb.~1.1.~ +5 -0
- data/test/test_one_syck.rb +5 -0
- data/test/test_rbyaml.rb +63 -32
- data/test/test_rbyaml.rb.~1.6.~ +59 -0
- data/test/{test_rbyaml.rb.~1.2.~ → test_rbyaml_old.rb} +13 -4
- data/test/test_time_events.rb +24 -0
- data/test/test_time_nodes.rb +24 -0
- data/test/test_time_tokens.rb +24 -0
- data/test/yaml/gems_new.yml +147456 -0
- data/test/yaml/test1.rb +8 -0
- data/test/yaml/test10.rb +14 -0
- data/test/yaml/test11.rb +13 -0
- data/test/yaml/test12.rb +9 -0
- data/test/yaml/test13.rb +9 -0
- data/test/yaml/test14.rb +13 -0
- data/test/yaml/test15.rb +12 -0
- data/test/yaml/test16.rb +11 -0
- data/test/yaml/test16.rb.~1.1.~ +11 -0
- data/test/yaml/test17.rb +10 -0
- data/test/yaml/test18.rb +13 -0
- data/test/yaml/test19.rb +9 -0
- data/test/yaml/test19.yml +1 -1
- data/test/yaml/test2.rb +8 -0
- data/test/yaml/test20.rb +11 -0
- data/test/yaml/test20.rb.~1.1.~ +9 -0
- data/test/yaml/test20.yml +1 -1
- data/test/yaml/test3.rb +13 -0
- data/test/yaml/test4.rb +13 -0
- data/test/yaml/test5.rb +8 -0
- data/test/yaml/test6.rb +10 -0
- data/test/yaml/test7.rb +15 -0
- data/test/yaml/test8.rb +15 -0
- data/test/yaml/test9.rb +13 -0
- metadata +61 -16
- data/lib/rbyaml/dumper.rb.~1.2.~ +0 -43
- data/lib/rbyaml/parser.rb.~1.2.~ +0 -494
data/lib/rbyaml/types.rb
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
# -*- mode: ruby; ruby-indent-level: 4 -*- vim: sw=4
|
2
|
+
#
|
3
|
+
# Classes required by the full core typeset
|
4
|
+
#
|
5
|
+
module RbYAML
|
6
|
+
#
|
7
|
+
# Default private type
|
8
|
+
#
|
9
|
+
class PrivateType
|
10
|
+
def self.tag_subclasses?; false; end
|
11
|
+
attr_accessor :type_id, :value
|
12
|
+
verbose, $VERBOSE = $VERBOSE, nil
|
13
|
+
def initialize( type, val )
|
14
|
+
@type_id = type; @value = val
|
15
|
+
@value.taguri = "x-private:#{ @type_id }"
|
16
|
+
end
|
17
|
+
def to_yaml_node( repr )
|
18
|
+
@value.to_yaml_node( repr )
|
19
|
+
end
|
20
|
+
ensure
|
21
|
+
$VERBOSE = verbose
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# Default domain type
|
26
|
+
#
|
27
|
+
class DomainType
|
28
|
+
def self.tag_subclasses?; false; end
|
29
|
+
attr_accessor :domain, :type_id, :value
|
30
|
+
verbose, $VERBOSE = $VERBOSE, nil
|
31
|
+
def initialize( domain, type, val )
|
32
|
+
@domain = domain; @type_id = type; @value = val
|
33
|
+
@value.taguri = "tag:#{ @domain }:#{ @type_id }"
|
34
|
+
end
|
35
|
+
def to_yaml_node( repr )
|
36
|
+
@value.to_yaml_node( repr )
|
37
|
+
end
|
38
|
+
ensure
|
39
|
+
$VERBOSE = verbose
|
40
|
+
end
|
41
|
+
|
42
|
+
#
|
43
|
+
# Builtin collection: !omap
|
44
|
+
#
|
45
|
+
class Omap < ::Array
|
46
|
+
yaml_as "tag:yaml.org,2002:omap"
|
47
|
+
def yaml_initialize( tag, val )
|
48
|
+
if Array === val
|
49
|
+
val.each do |v|
|
50
|
+
if Hash === v
|
51
|
+
concat( v.to_a ) # Convert the map to a sequence
|
52
|
+
else
|
53
|
+
raise YAML::Error, "Invalid !omap entry: " + val.inspect
|
54
|
+
end
|
55
|
+
end
|
56
|
+
else
|
57
|
+
raise YAML::Error, "Invalid !omap: " + val.inspect
|
58
|
+
end
|
59
|
+
self
|
60
|
+
end
|
61
|
+
def self.[]( *vals )
|
62
|
+
|
63
|
+
o = Omap.new
|
64
|
+
0.step( vals.length - 1, 2 ) do |i|
|
65
|
+
o[vals[i]] = vals[i+1]
|
66
|
+
end
|
67
|
+
o
|
68
|
+
end
|
69
|
+
def []( k )
|
70
|
+
self.assoc( k ).to_a[1]
|
71
|
+
end
|
72
|
+
def []=( k, *rest )
|
73
|
+
val, set = rest.reverse
|
74
|
+
if ( tmp = self.assoc( k ) ) and not set
|
75
|
+
tmp[1] = val
|
76
|
+
else
|
77
|
+
self << [ k, val ]
|
78
|
+
end
|
79
|
+
val
|
80
|
+
end
|
81
|
+
def has_key?( k )
|
82
|
+
self.assoc( k ) ? true : false
|
83
|
+
end
|
84
|
+
def is_complex_yaml?
|
85
|
+
true
|
86
|
+
end
|
87
|
+
def to_yaml_node( repr )
|
88
|
+
RbYAML::quick_emit_node( self.object_id, repr ) do |out|
|
89
|
+
out.seq( taguri, self.collect {|v| Hash[*v]}, to_yaml_style )
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Builtin collection: !pairs
|
96
|
+
#
|
97
|
+
class Pairs < ::Array
|
98
|
+
yaml_as "tag:yaml.org,2002:pairs"
|
99
|
+
def yaml_initialize( tag, val )
|
100
|
+
if Array === val
|
101
|
+
val.each do |v|
|
102
|
+
if Hash === v
|
103
|
+
concat( v.to_a ) # Convert the map to a sequence
|
104
|
+
else
|
105
|
+
raise YAML::Error, "Invalid !pairs entry: " + val.inspect
|
106
|
+
end
|
107
|
+
end
|
108
|
+
else
|
109
|
+
raise YAML::Error, "Invalid !pairs: " + val.inspect
|
110
|
+
end
|
111
|
+
self
|
112
|
+
end
|
113
|
+
def self.[]( *vals )
|
114
|
+
p = Pairs.new
|
115
|
+
0.step( vals.length - 1, 2 ) { |i|
|
116
|
+
p[vals[i]] = vals[i+1]
|
117
|
+
}
|
118
|
+
p
|
119
|
+
end
|
120
|
+
def []( k )
|
121
|
+
self.assoc( k ).to_a
|
122
|
+
end
|
123
|
+
def []=( k, val )
|
124
|
+
self << [ k, val ]
|
125
|
+
val
|
126
|
+
end
|
127
|
+
def has_key?( k )
|
128
|
+
self.assoc( k ) ? true : false
|
129
|
+
end
|
130
|
+
def is_complex_yaml?
|
131
|
+
true
|
132
|
+
end
|
133
|
+
def to_yaml_node( repr )
|
134
|
+
RbYAML::quick_emit_node( self.object_id, opts ) do |out|
|
135
|
+
out.seq( taguri, self.collect {|v| Hash[*v]}, to_yaml_style )
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
#
|
141
|
+
# Builtin collection: !set
|
142
|
+
#
|
143
|
+
class Set < ::Hash
|
144
|
+
yaml_as "tag:yaml.org,2002:set"
|
145
|
+
end
|
146
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class Object
|
2
|
+
def __is_str; false end
|
3
|
+
def __is_sym; false end
|
4
|
+
def __is_a; false end
|
5
|
+
def __is_int; false end
|
6
|
+
end
|
7
|
+
|
8
|
+
class String
|
9
|
+
def __is_str; true end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Symbol
|
13
|
+
def __is_sym; true end
|
14
|
+
end
|
15
|
+
|
16
|
+
class Array
|
17
|
+
def __is_a; true end
|
18
|
+
end
|
19
|
+
|
20
|
+
class Integer
|
21
|
+
def __is_int; true end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Fixnum
|
25
|
+
def __is_ascii_num
|
26
|
+
self <= ?9 && self >= ?0
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
module RbYAML
|
31
|
+
class PrivateType
|
32
|
+
attr_accessor :type_id, :value
|
33
|
+
def initialize( type, val )
|
34
|
+
@type_id = type;
|
35
|
+
@value = val
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/rbyaml/yaml.rb
CHANGED
@@ -48,24 +48,24 @@ module RbYAML
|
|
48
48
|
_load(stream, SafeLoader)
|
49
49
|
end
|
50
50
|
|
51
|
-
def self._emit(events, stream=nil,
|
51
|
+
def self._emit(events, stream=nil, dump=Dumper, opts={})
|
52
52
|
if stream.nil?
|
53
53
|
require 'stringio'
|
54
54
|
stream = StringIO.new
|
55
55
|
end
|
56
|
-
dumper =
|
56
|
+
dumper = dump.new(stream,opts)
|
57
57
|
for event in events
|
58
58
|
dumper.emit(event)
|
59
59
|
end
|
60
60
|
stream.string if StringIO === stream
|
61
61
|
end
|
62
62
|
|
63
|
-
def self._serialize_all(nodes,stream=nil,
|
63
|
+
def self._serialize_all(nodes,stream=nil, dump=Dumper, opts={})
|
64
64
|
if stream.nil?
|
65
65
|
require 'stringio'
|
66
66
|
stream = StringIO.new
|
67
67
|
end
|
68
|
-
dumper =
|
68
|
+
dumper = dump.new(stream,opts)
|
69
69
|
dumper.serializer.open
|
70
70
|
for node in nodes
|
71
71
|
dumper.serializer.serialize(node)
|
@@ -74,16 +74,16 @@ module RbYAML
|
|
74
74
|
stream.string if StringIO === stream
|
75
75
|
end
|
76
76
|
|
77
|
-
def self._serialize(node, stream=nil,
|
78
|
-
_serialize_all([node], stream,
|
77
|
+
def self._serialize(node, stream=nil, dump=Dumper, opts={})
|
78
|
+
_serialize_all([node], stream, dump, opts)
|
79
79
|
end
|
80
80
|
|
81
|
-
def self._dump_all(documents,stream=nil,
|
81
|
+
def self._dump_all(documents,stream=nil, dump=Dumper, opts={})
|
82
82
|
if stream.nil?
|
83
83
|
require 'stringio'
|
84
84
|
stream = StringIO.new
|
85
85
|
end
|
86
|
-
dumper =
|
86
|
+
dumper = dump.new(stream,opts)
|
87
87
|
dumper.serializer.open
|
88
88
|
for data in documents
|
89
89
|
dumper.representer.represent(data)
|
@@ -92,42 +92,32 @@ module RbYAML
|
|
92
92
|
stream.string if StringIO === stream
|
93
93
|
end
|
94
94
|
|
95
|
-
def self._dump(data, stream=nil,
|
96
|
-
_dump_all([data], stream,
|
95
|
+
def self._dump(data, stream=nil,dump=Dumper, opts={})
|
96
|
+
_dump_all([data], stream, dump, opts)
|
97
97
|
end
|
98
98
|
|
99
|
-
def self.
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
def self._safe_dump(data, stream=nil, *kwds)
|
104
|
-
_dump_all([data], stream, SafeDumper, *kwds)
|
105
|
-
end
|
106
|
-
|
107
|
-
def self._add_implicit_resolver(tag, regexp, first=nil, loader=Loader, dumper=Dumper)
|
108
|
-
loader.add_implicit_resolver(tag, regexp, first)
|
109
|
-
dumper.add_implicit_resolver(tag, regexp, first)
|
99
|
+
def self._add_implicit_resolver(tag, regexp, first=nil, resolver=BaseResolver)
|
100
|
+
resolver.add_implicit_resolver(tag, regexp, first)
|
110
101
|
end
|
111
102
|
|
112
|
-
def self._add_path_resolver(tag, path, kind=nil,
|
113
|
-
|
114
|
-
lumper.add_path_resolver(tag, path, kind)
|
103
|
+
def self._add_path_resolver(tag, path, kind=nil, resolver=BaseResolver)
|
104
|
+
resolver.add_path_resolver(tag, path, kind)
|
115
105
|
end
|
116
106
|
|
117
|
-
def self._add_constructor(tag, constructor,
|
118
|
-
|
107
|
+
def self._add_constructor(tag, constructor, ctor=Constructor)
|
108
|
+
ctor.add_constructor(tag, constructor)
|
119
109
|
end
|
120
110
|
|
121
|
-
def self._add_multi_constructor(tag_prefix, multi_constructor,
|
122
|
-
|
111
|
+
def self._add_multi_constructor(tag_prefix, multi_constructor, ctor=Constructor)
|
112
|
+
ctor.add_multi_constructor(tag_prefix, multi_constructor)
|
123
113
|
end
|
124
114
|
|
125
|
-
def self._add_representer(data_type, representer,
|
126
|
-
|
115
|
+
def self._add_representer(data_type, representer, rep=BaseRepresenter)
|
116
|
+
rep.add_representer(data_type, representer)
|
127
117
|
end
|
128
118
|
|
129
|
-
def self._add_multi_representer(data_type, multi_representer,
|
130
|
-
|
119
|
+
def self._add_multi_representer(data_type, multi_representer, rep=BaseRepresenter)
|
120
|
+
rep.add_multi_representer(data_type, multi_representer)
|
131
121
|
end
|
132
122
|
|
133
123
|
def self._dump_ruby_object(data, dumper=Dumper)
|
@@ -12,32 +12,32 @@ require 'rbyaml/dumper'
|
|
12
12
|
module RbYAML
|
13
13
|
def self._scan(stream, loader=Loader)
|
14
14
|
l = loader.new(stream)
|
15
|
-
yield l.get_token while l.check_token
|
15
|
+
yield l.scanner.get_token while l.scanner.check_token
|
16
16
|
end
|
17
17
|
|
18
18
|
def self._parse(stream, loader=Loader)
|
19
19
|
l = loader.new(stream)
|
20
|
-
yield l.get_event while l.check_event
|
20
|
+
yield l.parser.get_event while l.parser.check_event
|
21
21
|
end
|
22
22
|
|
23
23
|
def self._compose(stream, loader=Loader)
|
24
24
|
l = loader.new(stream)
|
25
|
-
l.get_node if l.check_node
|
25
|
+
l.composer.get_node if l.composer.check_node
|
26
26
|
end
|
27
27
|
|
28
28
|
def self._compose_all(stream, loader=Loader)
|
29
29
|
l = loader.new(stream)
|
30
|
-
yield l.get_node while l.check_node
|
30
|
+
yield l.composer.get_node while l.composer.check_node
|
31
31
|
end
|
32
32
|
|
33
33
|
def self._load_all(stream, loader=Loader)
|
34
34
|
l = loader.new(stream)
|
35
|
-
yield l.get_data while l.check_data
|
35
|
+
yield l.constructor.get_data while l.constructor.check_data
|
36
36
|
end
|
37
37
|
|
38
38
|
def self._load(stream, loader=Loader)
|
39
39
|
l = loader.new(stream)
|
40
|
-
l.get_data if l.check_data
|
40
|
+
l.constructor.get_data if l.constructor.check_data
|
41
41
|
end
|
42
42
|
|
43
43
|
def self._safe_load_all(stream)
|
@@ -60,17 +60,17 @@ module RbYAML
|
|
60
60
|
stream.string if StringIO === stream
|
61
61
|
end
|
62
62
|
|
63
|
-
def self._serialize_all(nodes,stream=nil,dumper=Dumper,default_style=nil,default_flow_style=nil,canonical=nil,indent=nil,width=nil,line_break=nil,explicit_start=
|
63
|
+
def self._serialize_all(nodes,stream=nil,dumper=Dumper,default_style=nil,default_flow_style=nil,canonical=nil,indent=nil,width=nil,line_break=nil,explicit_start=true,explicit_end=nil,version=nil,tags=nil)
|
64
64
|
if stream.nil?
|
65
65
|
require 'stringio'
|
66
66
|
stream = StringIO.new
|
67
67
|
end
|
68
|
-
dumper = dumper.new(stream,default_style,default_flow_style,canonical,indent,width,line_break,version,tags
|
69
|
-
dumper.open
|
68
|
+
dumper = dumper.new(stream,default_style,default_flow_style,canonical,indent,width,line_break,explicit_start,explicit_end,version,tags)
|
69
|
+
dumper.serializer.open
|
70
70
|
for node in nodes
|
71
|
-
dumper.serialize(node)
|
71
|
+
dumper.serializer.serialize(node)
|
72
72
|
end
|
73
|
-
dumper.close
|
73
|
+
dumper.serializer.close
|
74
74
|
stream.string if StringIO === stream
|
75
75
|
end
|
76
76
|
|
@@ -78,17 +78,17 @@ module RbYAML
|
|
78
78
|
_serialize_all([node], stream, dumper, *kwds)
|
79
79
|
end
|
80
80
|
|
81
|
-
def self._dump_all(documents,stream=nil,dumper=Dumper,default_style=nil,default_flow_style=nil,canonical=nil,indent=nil,width=nil,line_break=nil,explicit_start=
|
81
|
+
def self._dump_all(documents,stream=nil,dumper=Dumper,default_style=nil,default_flow_style=nil,canonical=nil,indent=nil,width=nil,line_break=nil,explicit_start=true,explicit_end=nil,version=nil,tags=nil)
|
82
82
|
if stream.nil?
|
83
83
|
require 'stringio'
|
84
84
|
stream = StringIO.new
|
85
85
|
end
|
86
|
-
dumper = dumper.new(stream,default_style,default_flow_style,canonical,indent,width,line_break,version,tags
|
87
|
-
dumper.open
|
86
|
+
dumper = dumper.new(stream,default_style,default_flow_style,canonical,indent,width,line_break,explicit_start,explicit_end,version,tags)
|
87
|
+
dumper.serializer.open
|
88
88
|
for data in documents
|
89
|
-
dumper.represent(data)
|
89
|
+
dumper.representer.represent(data)
|
90
90
|
end
|
91
|
-
dumper.close
|
91
|
+
dumper.serializer.close
|
92
92
|
stream.string if StringIO === stream
|
93
93
|
end
|
94
94
|
|
@@ -111,7 +111,7 @@ module RbYAML
|
|
111
111
|
|
112
112
|
def self._add_path_resolver(tag, path, kind=nil, loader=Loader, dumper=Dumper)
|
113
113
|
loader.add_path_resolver(tag, path, kind)
|
114
|
-
|
114
|
+
dumper.add_path_resolver(tag, path, kind)
|
115
115
|
end
|
116
116
|
|
117
117
|
def self._add_constructor(tag, constructor, loader=Loader)
|
data/test/load_one.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
$:.unshift File.join(File.dirname(__FILE__), "..", "lib")
|
2
|
+
|
3
|
+
require 'ostruct'
|
4
|
+
require 'rbyaml'
|
5
|
+
|
6
|
+
class TrueClass; def to_sym; :true end; end and class FalseClass; def to_sym; :false end; end
|
7
|
+
|
8
|
+
data = <<-"END"
|
9
|
+
---
|
10
|
+
x: 1
|
11
|
+
y: 2
|
12
|
+
z: 3
|
13
|
+
END
|
14
|
+
|
15
|
+
datay = <<-"END"
|
16
|
+
---
|
17
|
+
&verily
|
18
|
+
lemurs:
|
19
|
+
unite: *verily
|
20
|
+
beneath:
|
21
|
+
- patagonian
|
22
|
+
- bread
|
23
|
+
- products
|
24
|
+
thusly: [1, 2, 3, 4]
|
25
|
+
END
|
26
|
+
|
27
|
+
datax = <<-"END"
|
28
|
+
---
|
29
|
+
foo: 1
|
30
|
+
bar:
|
31
|
+
baz: [1, 2, 3]
|
32
|
+
quux: 42
|
33
|
+
doctors:
|
34
|
+
- William Hartnell
|
35
|
+
- Patrick Troughton
|
36
|
+
- Jon Pertwee
|
37
|
+
- Tom Baker
|
38
|
+
- Peter Davison
|
39
|
+
- Colin Baker
|
40
|
+
- Sylvester McCoy
|
41
|
+
- Paul McGann
|
42
|
+
- Christopher Eccleston
|
43
|
+
- David Tennant
|
44
|
+
a: {x: 1, w: 2, z: 3}
|
45
|
+
END
|
46
|
+
|
47
|
+
RbYAML.add_builtin_ctor("map") {|ctor,node|
|
48
|
+
OpenStruct.new(ctor.construct_mapping(node))
|
49
|
+
}
|
50
|
+
|
51
|
+
puts RbYAML.load(data)
|