RbYAML 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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