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.
Files changed (81) hide show
  1. data/lib/rbyaml.rb +14 -256
  2. data/lib/rbyaml.rb.~1.2.~ +383 -0
  3. data/lib/rbyaml/composer.rb +9 -11
  4. data/lib/rbyaml/{composer.rb.~1.2.~ → composer.rb.~1.3.~} +28 -25
  5. data/lib/rbyaml/constants.rb +95 -0
  6. data/lib/rbyaml/constructor.rb +180 -89
  7. data/lib/rbyaml/{constructor.rb.~1.2.~ → constructor.rb.~1.9.~} +137 -95
  8. data/lib/rbyaml/dumper.rb +12 -9
  9. data/lib/rbyaml/dumper.rb.~1.3.~ +36 -0
  10. data/lib/rbyaml/emitter.rb +14 -28
  11. data/lib/rbyaml/{emitter.rb.~1.2.~ → emitter.rb.~1.6.~} +22 -33
  12. data/lib/rbyaml/error.rb +4 -57
  13. data/lib/rbyaml/error.rb.~1.2.~ +75 -0
  14. data/lib/rbyaml/events.rb +8 -14
  15. data/lib/rbyaml/{events.rb.~1.2.~ → events.rb.~1.4.~} +29 -6
  16. data/lib/rbyaml/nodes.rb +5 -5
  17. data/lib/rbyaml/{nodes.rb.~1.2.~ → nodes.rb.~1.3.~} +13 -9
  18. data/lib/rbyaml/parser.rb +70 -108
  19. data/lib/rbyaml/parser.rb.~1.4.~ +632 -0
  20. data/lib/rbyaml/representer.rb +19 -157
  21. data/lib/rbyaml/representer.rb.old +317 -0
  22. data/lib/rbyaml/{representer.rb.~1.2.~ → representer.rb.~1.5.~} +60 -26
  23. data/lib/rbyaml/resolver.rb +6 -6
  24. data/lib/rbyaml/{resolver.rb.~1.1.~ → resolver.rb.~1.6.~} +20 -20
  25. data/lib/rbyaml/rubytypes.rb +391 -0
  26. data/lib/rbyaml/scanner.rb +123 -225
  27. data/lib/rbyaml/{scanner.rb.~1.2.~ → scanner.rb.~1.5.~} +466 -378
  28. data/lib/rbyaml/serializer.rb +9 -9
  29. data/lib/rbyaml/{serializer.rb.~1.2.~ → serializer.rb.~1.4.~} +19 -17
  30. data/lib/rbyaml/stream.rb +48 -0
  31. data/lib/rbyaml/tag.rb +72 -0
  32. data/lib/rbyaml/tokens.rb +22 -16
  33. data/lib/rbyaml/{tokens.rb.~1.2.~ → tokens.rb.~1.3.~} +44 -4
  34. data/lib/rbyaml/types.rb +146 -0
  35. data/lib/rbyaml/util.rb.~1.3.~ +38 -0
  36. data/lib/rbyaml/yaml.rb +22 -32
  37. data/lib/rbyaml/{yaml.rb.~1.2.~ → yaml.rb.~1.5.~} +17 -17
  38. data/test/load_one.rb +6 -0
  39. data/test/load_one_yaml.rb +6 -0
  40. data/test/output_events.rb +9 -0
  41. data/test/test_add_ctor.rb +51 -0
  42. data/test/test_add_ctor.rb.~1.1.~ +30 -0
  43. data/test/test_bm.rb +2 -2
  44. data/test/test_bm.rb.~1.1.~ +28 -0
  45. data/test/test_gems.rb +10 -0
  46. data/test/test_one.rb.~1.1.~ +5 -0
  47. data/test/test_one_syck.rb +5 -0
  48. data/test/test_rbyaml.rb +63 -32
  49. data/test/test_rbyaml.rb.~1.6.~ +59 -0
  50. data/test/{test_rbyaml.rb.~1.2.~ → test_rbyaml_old.rb} +13 -4
  51. data/test/test_time_events.rb +24 -0
  52. data/test/test_time_nodes.rb +24 -0
  53. data/test/test_time_tokens.rb +24 -0
  54. data/test/yaml/gems_new.yml +147456 -0
  55. data/test/yaml/test1.rb +8 -0
  56. data/test/yaml/test10.rb +14 -0
  57. data/test/yaml/test11.rb +13 -0
  58. data/test/yaml/test12.rb +9 -0
  59. data/test/yaml/test13.rb +9 -0
  60. data/test/yaml/test14.rb +13 -0
  61. data/test/yaml/test15.rb +12 -0
  62. data/test/yaml/test16.rb +11 -0
  63. data/test/yaml/test16.rb.~1.1.~ +11 -0
  64. data/test/yaml/test17.rb +10 -0
  65. data/test/yaml/test18.rb +13 -0
  66. data/test/yaml/test19.rb +9 -0
  67. data/test/yaml/test19.yml +1 -1
  68. data/test/yaml/test2.rb +8 -0
  69. data/test/yaml/test20.rb +11 -0
  70. data/test/yaml/test20.rb.~1.1.~ +9 -0
  71. data/test/yaml/test20.yml +1 -1
  72. data/test/yaml/test3.rb +13 -0
  73. data/test/yaml/test4.rb +13 -0
  74. data/test/yaml/test5.rb +8 -0
  75. data/test/yaml/test6.rb +10 -0
  76. data/test/yaml/test7.rb +15 -0
  77. data/test/yaml/test8.rb +15 -0
  78. data/test/yaml/test9.rb +13 -0
  79. metadata +61 -16
  80. data/lib/rbyaml/dumper.rb.~1.2.~ +0 -43
  81. data/lib/rbyaml/parser.rb.~1.2.~ +0 -494
@@ -1,5 +1,5 @@
1
-
2
1
  require 'set'
2
+ require 'date'
3
3
 
4
4
  require 'rbyaml/error'
5
5
  require 'rbyaml/nodes'
@@ -9,13 +9,9 @@ module RbYAML
9
9
  end
10
10
 
11
11
  class BaseRepresenter
12
- @@yaml_representers = {}
13
- @@yaml_multi_representers = {}
14
-
15
- def initialize(serializer, default_style=nil, default_flow_style=nil)
12
+ def initialize(serializer, opts={})
16
13
  @serializer = serializer
17
- @default_style = default_style
18
- @default_flow_style = default_flow_style
14
+ @default_style = opts[:UseDouble] ? '"' : (opts[:UseSingle] ? "'" : nil)
19
15
  @represented_objects = {}
20
16
  end
21
17
 
@@ -24,17 +20,7 @@ module RbYAML
24
20
  @serializer.serialize(node)
25
21
  represented_objects = {}
26
22
  end
27
-
28
- CLASSOBJ_TYPE = Class
29
- INSTANCE_TYPE = Object
30
- FUNCTION_TYPE = Method
31
- BUILTIN_FUNCTION_TYPE = Method
32
- MODULE_TYPE = Module
33
-
34
- def get_classobj_bases(cls)
35
- [cls] + cls.ancestors
36
- end
37
-
23
+
38
24
  def represent_data(data)
39
25
  if ignore_aliases(data)
40
26
  alias_key = nil
@@ -50,56 +36,27 @@ module RbYAML
50
36
  end
51
37
  @represented_objects[alias_key] = nil
52
38
  end
53
-
54
- data_types = data.class.ancestors
55
- data_types = get_classobj_bases(data.class) + data_types if INSTANCE_TYPE === data
56
-
57
- if @@yaml_representers.include?(data_types[0])
58
- node = send(@@yaml_representers[data_types[0]],data)
59
- else
60
- rerun = true
61
- for data_type in data_types
62
- if @@yaml_multi_representers.include?(data_type)
63
- node = send(@@yaml_multi_representers[data_type],data)
64
- rerun = false
65
- break
66
- elsif @@yaml_representers.include?(data_type)
67
- node = send(@@yaml_representers[data_type],data)
68
- rerun = false
69
- break
70
- end
71
- end
72
- if rerun
73
- if @@yaml_multi_representers.include?(nil)
74
- node = send(@@yaml_multi_representers[nil],data)
75
- elsif @@yaml_representers.include?(nil)
76
- node = send(@@yaml_representers[nil],data)
77
- else
78
- node = ScalarNode.new(nil, data)
79
- end
80
- end
81
- end
82
-
39
+ node = data.to_yaml_node(self)
83
40
  @represented_objects[alias_key] = node if !alias_key.nil?
84
41
  node
85
42
  end
86
43
 
87
- def self.add_representer(data_type, representer)
88
- @@yaml_representers[data_type] = representer
44
+ def scalar(tag, value, style=nil)
45
+ represent_scalar(tag,value,style)
89
46
  end
90
47
 
91
- def self.add_multi_representer(data_type, representer)
92
- @@yaml_multi_representers[data_type] = representer
93
- end
94
-
95
48
  def represent_scalar(tag, value, style=nil)
96
49
  style ||= @default_style
97
- ScalarNode.new(tag, value, style)
50
+ ScalarNode.new(tag,value,style)
51
+ end
52
+
53
+ def seq(tag, sequence, flow_style=nil)
54
+ represent_sequence(tag,sequence,flow_style)
98
55
  end
99
56
 
100
57
  def represent_sequence(tag, sequence, flow_style=nil)
101
- best_style = true
102
- value = sequence.map {|item|
58
+ best_style = false
59
+ value = sequence.map {|item|
103
60
  node_item = represent_data(item)
104
61
  best_style = false if !node_item.__is_scalar && !node_item.flow_style
105
62
  node_item
@@ -108,8 +65,12 @@ module RbYAML
108
65
  SequenceNode.new(tag, value, flow_style)
109
66
  end
110
67
 
68
+ def map(tag, mapping, flow_style=nil)
69
+ represent_mapping(tag,mapping,flow_style)
70
+ end
71
+
111
72
  def represent_mapping(tag, mapping, flow_style=nil)
112
- best_style = true
73
+ best_style = false
113
74
  if mapping.respond_to?(:keys)
114
75
  value = {}
115
76
  for item_key,item_value in mapping
@@ -139,110 +100,11 @@ module RbYAML
139
100
  end
140
101
 
141
102
  class SafeRepresenter < BaseRepresenter
142
-
143
103
  def ignore_aliases(data)
144
104
  data.nil? || data.__is_str || TrueClass === data || FalseClass === data || data.__is_int || Float === data
145
105
  end
146
-
147
- def represent_none(data)
148
- represent_scalar(data.taguri,"null")
149
- end
150
-
151
- def represent_str(data)
152
- represent_scalar(data.taguri,data,nil)
153
- end
154
-
155
- def represent_symbol(data)
156
- represent_scalar(data.taguri,data.to_s)
157
- end
158
-
159
- def represent_bool(data)
160
- value = data ? "true" : "false"
161
- represent_scalar('tag:yaml.org,2002:bool',value)
162
- end
163
-
164
- def represent_int(data)
165
- represent_scalar(data.taguri,data.to_s)
166
- end
167
-
168
- def represent_float(data)
169
- if data.infinite? == 1
170
- value = ".inf"
171
- elsif data.infinite? == -1
172
- value = "-.inf"
173
- elsif data.nan? || data != data
174
- value = ".nan"
175
- else
176
- value = data.to_s
177
- end
178
- represent_scalar(data.taguri, value)
179
- end
180
-
181
- def represent_list(data)
182
- #no support for pairs right now. should probably be there, though...
183
- represent_sequence(data.taguri, data)
184
- end
185
-
186
- def represent_dict(data)
187
- represent_mapping(data.taguri, data)
188
- end
189
-
190
- def represent_set(data)
191
- value = {}
192
- for key in data
193
- value[key] = nil
194
- end
195
- represent_mapping(data.taguri, value)
196
- end
197
-
198
- def represent_datetime(data)
199
- value = "%04d-%02d-%02d %02d:%02d:%02d" % [data.year, data.month, data.day, data.hour, data.min, data.sec]
200
- if data.usec != 0
201
- value += "." + (data.usec/1000000.0).to_s.split(/\./)[1]
202
- end
203
- if data.utc_offset != 0
204
- value += data.utc_offset.to_s
205
- end
206
- represent_scalar(data.taguri, value)
207
- end
208
-
209
- def represent_ruby(data)
210
- state = data.to_yaml_properties
211
- map = {}
212
- state.each do |m|
213
- map[m[1..-1]] = data.instance_variable_get(m)
214
- end
215
- represent_mapping("!ruby/object:#{data.class.yaml_tag_class_name}", map,nil)
216
- end
217
-
218
- def represent_yaml_object(tag, data, flow_style=nil)
219
- state = data.to_yaml_properties
220
- map = {}
221
- state.each do |m|
222
- map[m[1..-1]] = data.instance_variable_get(m)
223
- end
224
- represent_mapping(tag, map, flow_style)
225
- end
226
-
227
- def represent_undefined(data)
228
- raise RepresenterError.new("cannot represent an object: #{data}")
229
- end
230
106
  end
231
107
 
232
- BaseRepresenter.add_representer(NilClass,:represent_none)
233
- BaseRepresenter.add_representer(String,:represent_str)
234
- BaseRepresenter.add_representer(Symbol,:represent_symbol)
235
- BaseRepresenter.add_representer(TrueClass,:represent_bool)
236
- BaseRepresenter.add_representer(FalseClass,:represent_bool)
237
- BaseRepresenter.add_representer(Integer,:represent_int)
238
- BaseRepresenter.add_representer(Float,:represent_float)
239
- BaseRepresenter.add_representer(Array,:represent_list)
240
- BaseRepresenter.add_representer(Hash,:represent_dict)
241
- BaseRepresenter.add_representer(Set,:represent_set)
242
- BaseRepresenter.add_representer(Time,:represent_datetime)
243
- BaseRepresenter.add_representer(Object,:represent_ruby)
244
- BaseRepresenter.add_representer(nil,:represent_undefined)
245
-
246
108
  class Representer < SafeRepresenter
247
109
  end
248
110
  end
@@ -0,0 +1,317 @@
1
+
2
+ require 'set'
3
+ require 'date'
4
+
5
+ require 'rbyaml/error'
6
+ require 'rbyaml/nodes'
7
+
8
+ module RbYAML
9
+ class RepresenterError < YAMLError
10
+ end
11
+
12
+ class BaseRepresenter
13
+ @@yaml_representers = {}
14
+ @@yaml_multi_representers = {}
15
+
16
+ attr_writer :helper
17
+ attr_reader :serializer
18
+
19
+ def initialize(serializer, opts={})
20
+ @serializer = serializer
21
+ @default_style = opts[:UseDouble] ? '"' : (opts[:UseSingle] ? "'" : nil)
22
+ @represented_objects = {}
23
+ end
24
+
25
+ def represent(data)
26
+ node = represent_data(data)
27
+ @serializer.serialize(node)
28
+ represented_objects = {}
29
+ end
30
+
31
+ def get_classobj_bases(cls)
32
+ [cls] + cls.ancestors
33
+ end
34
+
35
+ def represent_data(data)
36
+ if ignore_aliases(data)
37
+ alias_key = nil
38
+ else
39
+ alias_key = data.object_id
40
+ end
41
+
42
+ if !alias_key.nil?
43
+ if @represented_objects.include?(alias_key)
44
+ node = @represented_objects[alias_key]
45
+ raise RepresenterError.new("recursive objects are not allowed: #{data}") if node.nil?
46
+ return node
47
+ end
48
+ @represented_objects[alias_key] = nil
49
+ end
50
+
51
+ data.to_yaml(@helper || RepresenterHelper.new(self))
52
+
53
+ data_types = data.class.ancestors
54
+ data_types = get_classobj_bases(data.class) + data_types
55
+
56
+ if @@yaml_representers.include?(data_types[0])
57
+ node = send(@@yaml_representers[data_types[0]],data)
58
+ else
59
+ rerun = true
60
+ for data_type in data_types
61
+ if @@yaml_multi_representers.include?(data_type)
62
+ node = send(@@yaml_multi_representers[data_type],data)
63
+ rerun = false
64
+ break
65
+ elsif @@yaml_representers.include?(data_type)
66
+ node = send(@@yaml_representers[data_type],data)
67
+ rerun = false
68
+ break
69
+ end
70
+ end
71
+ if rerun
72
+ if @@yaml_multi_representers.include?(nil)
73
+ node = send(@@yaml_multi_representers[nil],data)
74
+ elsif @@yaml_representers.include?(nil)
75
+ node = send(@@yaml_representers[nil],data)
76
+ else
77
+ node = ScalarNode.new(nil, data)
78
+ end
79
+ end
80
+ end
81
+
82
+ @represented_objects[alias_key] = node if !alias_key.nil?
83
+ node
84
+ end
85
+
86
+ def self.add_representer(data_type, representer)
87
+ @@yaml_representers[data_type] = representer
88
+ end
89
+
90
+ def self.add_multi_representer(data_type, representer)
91
+ @@yaml_multi_representers[data_type] = representer
92
+ end
93
+
94
+ def represent_scalar(tag, value, style=nil)
95
+ style ||= @default_style
96
+ ScalarNode.new(tag,value,style)
97
+ end
98
+
99
+ def represent_sequence(tag, sequence, flow_style=nil)
100
+ best_style = false
101
+ value = sequence.map {|item|
102
+ node_item = represent_data(item)
103
+ best_style = false if !node_item.__is_scalar && !node_item.flow_style
104
+ node_item
105
+ }
106
+ flow_style ||= (@flow_default_style || best_style)
107
+ SequenceNode.new(tag, value, flow_style)
108
+ end
109
+
110
+ def represent_mapping(tag, mapping, flow_style=nil)
111
+ best_style = false
112
+ if mapping.respond_to?(:keys)
113
+ value = {}
114
+ for item_key,item_value in mapping
115
+ node_key = represent_data(item_key)
116
+ node_value = represent_data(item_value)
117
+ best_style = false if !node_key.__is_scalar && !node_key.flow_style
118
+ best_style = false if !node_value.__is_scalar && !node_value.flow_style
119
+ value[node_key] = node_value
120
+ end
121
+ else
122
+ value = []
123
+ for item_key, item_value in mapping
124
+ node_key = represent_data(item_key)
125
+ node_value = represent_data(item_value)
126
+ best_style = false if !node_key.__is_scalar && !node_key.flow_style
127
+ best_style = false if !node_value.__is_scalar && !node_value.flow_style
128
+ value << [node_key, node_value]
129
+ end
130
+ end
131
+ flow_style ||= (@flow_default_style || best_style)
132
+ MappingNode.new(tag, value, flow_style)
133
+ end
134
+
135
+ def ignore_aliases(data)
136
+ false
137
+ end
138
+ end
139
+
140
+ class SafeRepresenter < BaseRepresenter
141
+
142
+ def ignore_aliases(data)
143
+ data.nil? || data.__is_str || TrueClass === data || FalseClass === data || data.__is_int || Float === data
144
+ end
145
+
146
+ def represent_none(data)
147
+ # represent_scalar(data.taguri,"null")
148
+ represent_scalar('tag:yaml.org,2002:str',"")
149
+ end
150
+
151
+ NON_PRINTABLE = /[^\x09\x0A\x0D\x20-\x7E\x85\xA0-\xFF]/
152
+ def represent_str(data)
153
+ style = nil
154
+ if NON_PRINTABLE =~ data
155
+ data = Base64.encode64(data)
156
+ data.taguri ="tag:yaml.org,2002:binary"
157
+ style = "|"
158
+ end
159
+ represent_scalar(data.taguri,data,style)
160
+ end
161
+
162
+ def represent_symbol(data)
163
+ represent_scalar(data.taguri,data.to_s)
164
+ end
165
+
166
+ def represent_private_type(data)
167
+ represent_scalar(data.type_id,data.value)
168
+ end
169
+
170
+ def represent_bool(data)
171
+ value = data ? "true" : "false"
172
+ represent_scalar('tag:yaml.org,2002:bool',value)
173
+ end
174
+
175
+ def represent_int(data)
176
+ represent_scalar(data.taguri,data.to_s)
177
+ end
178
+
179
+ def represent_float(data)
180
+ if data.infinite? == 1
181
+ value = ".inf"
182
+ elsif data.infinite? == -1
183
+ value = "-.inf"
184
+ elsif data.nan? || data != data
185
+ value = ".nan"
186
+ else
187
+ value = data.to_s
188
+ end
189
+ represent_scalar(data.taguri, value)
190
+ end
191
+
192
+ def represent_list(data)
193
+ #no support for pairs right now. should probably be there, though...
194
+ represent_sequence(data.taguri, data)
195
+ end
196
+
197
+ def represent_dict(data)
198
+ represent_mapping(data.taguri, data)
199
+ end
200
+
201
+ def represent_set(data)
202
+ value = {}
203
+ for key in data
204
+ value[key] = nil
205
+ end
206
+ represent_mapping(data.taguri, value)
207
+ end
208
+
209
+ def represent_date(data)
210
+ represent_scalar('tag:yaml.org,2002:timestamp',data.to_s)
211
+ end
212
+
213
+ def represent_datetime(data)
214
+ tz = "Z"
215
+ # from the tidy Tobias Peters <t-peters@gmx.de> Thanks!
216
+ unless data.utc?
217
+ utc_same_instant = data.dup.utc
218
+ utc_same_writing = Time.utc(data.year,data.month,data.day,data.hour,data.min,data.sec,data.usec)
219
+ difference_to_utc = utc_same_writing - utc_same_instant
220
+ if (difference_to_utc < 0)
221
+ difference_sign = '-'
222
+ absolute_difference = -difference_to_utc
223
+ else
224
+ difference_sign = '+'
225
+ absolute_difference = difference_to_utc
226
+ end
227
+ difference_minutes = (absolute_difference/60).round
228
+ tz = "%s%02d:%02d" % [ difference_sign, difference_minutes / 60, difference_minutes % 60]
229
+ end
230
+ standard = data.strftime( "%Y-%m-%d %H:%M:%S" )
231
+ standard += ".%06d" % [data.usec] if data.usec.nonzero?
232
+ standard += " %s" % [tz]
233
+ represent_scalar(data.taguri, standard)
234
+ end
235
+
236
+ def represent_ruby(data)
237
+ state = data.to_yaml_properties
238
+ map = {}
239
+ state.each do |m|
240
+ map[m[1..-1]] = data.instance_variable_get(m)
241
+ end
242
+ represent_mapping("!ruby/object:#{data.class.yaml_tag_class_name}", map,nil)
243
+ end
244
+
245
+ def represent_yaml_object(tag, data, flow_style=nil)
246
+ state = data.to_yaml_properties
247
+ map = {}
248
+ state.each do |m|
249
+ map[m[1..-1]] = data.instance_variable_get(m)
250
+ end
251
+ represent_mapping(tag, map, flow_style)
252
+ end
253
+
254
+ def represent_undefined(data)
255
+ raise RepresenterError.new("cannot represent an object: #{data}")
256
+ end
257
+ end
258
+
259
+ BaseRepresenter.add_representer(NilClass,:represent_none)
260
+ BaseRepresenter.add_representer(String,:represent_str)
261
+ BaseRepresenter.add_representer(Symbol,:represent_symbol)
262
+ BaseRepresenter.add_representer(TrueClass,:represent_bool)
263
+ BaseRepresenter.add_representer(FalseClass,:represent_bool)
264
+ BaseRepresenter.add_representer(Integer,:represent_int)
265
+ BaseRepresenter.add_representer(Float,:represent_float)
266
+ BaseRepresenter.add_representer(Array,:represent_list)
267
+ BaseRepresenter.add_representer(Hash,:represent_dict)
268
+ BaseRepresenter.add_representer(Set,:represent_set)
269
+ BaseRepresenter.add_representer(Time,:represent_datetime)
270
+ BaseRepresenter.add_representer(Date,:represent_date)
271
+ BaseRepresenter.add_representer(PrivateType,:represent_private_type)
272
+ BaseRepresenter.add_representer(Object,:represent_ruby)
273
+ BaseRepresenter.add_representer(nil,:represent_undefined)
274
+
275
+ class Representer < SafeRepresenter
276
+ end
277
+
278
+ class RepresenterHelper
279
+ def initialize(representer)
280
+ @representer = representer
281
+ @representer.helper = self
282
+ end
283
+
284
+ #
285
+ # Quick mapping
286
+ #
287
+ def map( type, &e )
288
+ val = Mapping.new
289
+ e.call(val)
290
+ @representer.serializer.serialize(represent_mapping(type,val))
291
+ end
292
+
293
+ #
294
+ # Quick sequence
295
+ #
296
+ def seq( type, &e )
297
+ val = Sequence.new
298
+ e.call( val )
299
+ @representer.serializer.serialize(represent_sequence(type,val))
300
+ end
301
+ end
302
+
303
+ #
304
+ # Emitter helper classes
305
+ #
306
+ class Mapping < Hash
307
+ def add( k, v )
308
+ self[k] = v
309
+ end
310
+ end
311
+
312
+ class Sequence < Array
313
+ def add( v )
314
+ push v
315
+ end
316
+ end
317
+ end