csv2hash 0.5.0 → 0.6.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 043c4be4542235e09772f8ca2249288158f7230f
4
- data.tar.gz: 2eb0e8d2a0e13854f103b21b34d4a54fbb55e64f
3
+ metadata.gz: 12502614a6a2f8d3243b4b35152bc6dc33cc3f60
4
+ data.tar.gz: 235432257ee6d4e907aaa900f5090fc284fc80db
5
5
  SHA512:
6
- metadata.gz: 43c070b76ca768925631f70c3e95750b5ec7edf9438e856ee58160c288f04a9c6d2215bc04c01af7a464ef80a991c1adb88797b5f4183d7c53922b1d09ca893b
7
- data.tar.gz: 62050c84397a144b712a592cc9e39d28d1bec6965fdbe31d35263016cf31a4b4a35b2450538088da239583ed76a0d9ce7e8ec0c3e129176792ed39e5a6c06715
6
+ metadata.gz: 5f597444c037b909413309e3570374c074a18e96463c40c1c7979cd5aeec5f96f6203ade714959c4ca930341e90d4b67a39f2b3718f02c57e85cf4882b6594d5
7
+ data.tar.gz: e9488827e829ecdc086791c8beadc0afcf5dd868327fbf0c78a479f963d19608a50e581d6974366dacbac9fed4ce289741c8c9971098dddbf90f7e374e0f8bb2
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- csv2hash (0.5.0)
4
+ csv2hash (0.6.0)
5
5
  activesupport (~> 4.1)
6
6
 
7
7
  GEM
data/README.md CHANGED
@@ -28,6 +28,19 @@ Or install it yourself as:
28
28
 
29
29
  Parsing is based on rules, you must defined rules of parsing
30
30
 
31
+ ### DSL
32
+
33
+ Csv2hash::Main.generate_definition :name do
34
+ set_type { Definition::MAPPING }
35
+ set_header_size { 2 } # 0 by default
36
+ set_structure_rules {{ 'MaxColumns' => 2 }}
37
+ mapping do
38
+ cell position: [0,0], key: 'gender'
39
+ cell position: [1,0], key: 'name'
40
+ end
41
+ end
42
+ Csv2hash::Main[:name] # Access anywhere
43
+
31
44
  ### Rules
32
45
 
33
46
  You should declared a definition for you CSV, and then define for each cell what you would expect.
@@ -37,31 +50,31 @@ Example :
37
50
  If you want the very first cell, located on the first line and on the first column to be a string with values are either 'yes' either 'no', you can write the following validation rule:
38
51
 
39
52
  ```
40
- { name: 'aswering', type: 'string', values: ['yes', 'no'], position: [0,0] }
53
+ cell name: 'aswering', type: 'string', values: ['yes', 'no'], position: [0,0]
41
54
  ```
42
55
 
43
56
  :type attribute has 'string' for default value, therefore you can just write this:
44
57
 
45
58
  ```
46
- { name: 'aswering', values: ['yes', 'no'], position: [0,0] }
59
+ cell name: 'aswering', values: ['yes', 'no'], position: [0,0]
47
60
  ```
48
61
 
49
62
  You can define you own message but default message is 'undefined :key on :position'
50
63
 
51
64
  ```
52
- { name: 'aswering', values: ['yes', 'no'], position: [0,0], message: 'this value is not supported' }
65
+ cell name: 'aswering', values: ['yes', 'no'], position: [0,0], message: 'this value is not supported'
53
66
  ```
54
67
 
55
68
  You can also define Range of values
56
69
 
57
70
  ```
58
- { name: 'score', values: 0..5, position: [0,0] }
71
+ cell name: 'score', values: 0..5, position: [0,0]
59
72
  ```
60
73
 
61
74
  The message is parsed:
62
75
 
63
76
  ```
64
- { ..., message: 'value of :name is not supported, please you one of :values' }
77
+ cell ..., message: 'value of :name is not supported, please you one of :values'
65
78
  ```
66
79
 
67
80
  It produces :
@@ -119,20 +132,21 @@ Precise position validation sample:
119
132
  end
120
133
 
121
134
  def data
122
- @data_wrapper ||= Csv2hash::Main.new(definition, file_path_or_data).parse
135
+ @data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:<definition_name>], file_path_or_data).parse
123
136
  end
124
137
 
125
138
  private
126
139
 
127
- def rules
128
- [].tap do |mapping|
129
- mapping << { position: [2,1], key: 'first_name' }
130
- mapping << { position: [3,1], key: 'last_name' }
131
- end
132
- end
133
-
134
140
  def definition
135
- Csv2Hash::Definition.new(rules, type = Csv2Hash::Definition::MAPPING, header_size: 1)
141
+ Main.generate_definition :my_defintion do
142
+ set_type { Definition::MAPPING }
143
+ set_header_size { 1 }
144
+ mapping do
145
+ cell position: [2,1], key: 'first_name'
146
+ cell position: [3,1], key: 'last_name'
147
+ end
148
+ end
149
+ end
136
150
  end
137
151
 
138
152
  end
@@ -159,23 +173,28 @@ Collection validation sample:
159
173
  end
160
174
 
161
175
  def data
162
- @data_wrapper ||= Csv2hash::Main.new(definition, file_path_or_data).parse
176
+ @data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:<definition_name>], file_path_or_data).parse
163
177
  end
164
178
 
165
179
  private
166
180
 
167
- def rules
168
- [].tap do |mapping|
169
- mapping << { position: 0, key: 'nickname' }
170
- mapping << { position: 1, key: 'first_name' }
171
- mapping << { position: 2, key: 'last_name' }
172
- end
173
- end
174
-
175
181
  def definition
176
182
  Csv2Hash::Definition.new(rules, type = Csv2Hash::Definition::COLLECTION, header_size: 1)
177
183
  end
178
184
 
185
+ def definition
186
+ Main.generate_definition :my_defintion do
187
+ set_type { Definition::COLLECTION }
188
+ set_header_size { 1 }
189
+ mapping do
190
+ cell position: 0, key: 'nickname'
191
+ cell position: 1, key: 'first_name'
192
+ cell position: 2, key: 'last_name'
193
+ end
194
+ end
195
+ end
196
+ end
197
+
179
198
  end
180
199
  ```
181
200
 
@@ -194,22 +213,23 @@ Current validations are: MinColumn, MaxColumn
194
213
  end
195
214
 
196
215
  def data
197
- @data_wrapper ||= Csv2hash::Main.new(definition, file_path_or_data).parse
216
+ @data_wrapper ||= Csv2hash::Main.new(Csv2hash::Main[:<definition_name>], file_path_or_data).parse
198
217
  end
199
218
 
200
219
  private
201
220
 
202
- def rules
203
- [].tap do |mapping|
204
- mapping << { position: 0, key: 'nickname' }
205
- mapping << { position: 1, key: 'first_name' }
206
- mapping << { position: 2, key: 'last_name' }
207
- end
208
- end
209
-
210
221
  def definition
211
- Csv2Hash::Definition.new(rules, type = Csv2Hash::Definition::COLLECTION,
212
- structure_rules: { 'MinColumns' => 2, 'MaxColumns' => 3 })
222
+ Main.generate_definition :my_defintion do
223
+ set_type { Definition::COLLECTION }
224
+ set_header_size { 1 }
225
+ set_structure_rules {{ 'MinColumns' => 2, 'MaxColumns' => 3 }}
226
+ mapping do
227
+ cell position: 0, key: 'nickname'
228
+ cell position: 1, key: 'first_name'
229
+ cell position: 2, key: 'last_name'
230
+ end
231
+ end
232
+ end
213
233
  end
214
234
  end
215
235
  ```
@@ -219,7 +239,7 @@ Current validations are: MinColumn, MaxColumn
219
239
  You can define the number of rows to skip in the header of the CSV.
220
240
 
221
241
  ```
222
- Definition.new(rules, type, header_size: 0)
242
+ set_header_size { 1 }
223
243
  ```
224
244
 
225
245
  ### Parser and configuration
@@ -343,8 +363,8 @@ For downcase validation
343
363
  in your rule
344
364
 
345
365
  ```
346
- { position: [0,0], key: 'name', extra_validator: DowncaseValidator.new,
347
- message: 'your data should be written in lowercase only.' }
366
+ cell position: [0,0], key: 'name', extra_validator: DowncaseValidator.new,
367
+ message: 'your data should be written in lowercase only.'
348
368
  ```
349
369
 
350
370
  Csv data
@@ -353,6 +373,30 @@ Csv data
353
373
  [ [ 'Foo' ] ]
354
374
  ```
355
375
 
376
+ # Upgrading
377
+
378
+ # Upgrading from 0.5 to 0.6
379
+
380
+ Introduce DSL
381
+
382
+ Prior to 0.6 :
383
+
384
+ ```
385
+ rules = [{ position: [0,0], key: 'name' }]
386
+ Csv2hash::Definition.new(rules, Definition::MAPPING, options={})
387
+
388
+ ```
389
+
390
+ Starting from 0.6 :
391
+
392
+ ```
393
+ Csv2hash::Main.generate_definition :foo do
394
+ set_type { Definition::MAPPING }
395
+ mapping { cell position: [0,0], key: 'name' }
396
+ end
397
+ Csv2hash::Main[:foo] # Access anywhere
398
+ ```
399
+
356
400
  # Upgrading from 0.4 to 0.5
357
401
 
358
402
  Signature of ```Csv2hash::Main#new``` has changed too
data/ReleaseNotes.md CHANGED
@@ -1,10 +1,18 @@
1
+ ### VERSION 0.6.0
2
+
3
+ * backwards incompatible changes
4
+ * Introduce DSL for definition
5
+
6
+ * refactoring
7
+ * replace arguments for rules by DSL of cells
8
+
1
9
  ### VERSION 0.5.0
2
10
 
3
11
  * backwards incompatible changes
4
12
  * The signature of Csv2hash::Main#new has changed.
5
13
 
6
14
  * refactoring
7
- * remove params ``` ignore_blank_line ``` to benefit of options of Hash
15
+ * remove params ``` ignore_blank_line ``` to benefit of options of Hash
8
16
 
9
17
  ### VERSION 0.4.0
10
18
 
data/bin/launch_irb ADDED
@@ -0,0 +1 @@
1
+ irb -r csv2hash -I ./lib
@@ -5,7 +5,6 @@ module Csv2hash
5
5
  class UnsupportedAdapter < StandardError ; end
6
6
 
7
7
  def self.create adapter_name, file_path_or_data
8
- # binding.pry
9
8
  load "csv2hash/adapters/#{adapter_name}_adapter.rb"
10
9
  class_eval("Csv2hash::Adapter::#{klass_adapter(adapter_name)}").new file_path_or_data
11
10
  end
@@ -0,0 +1,11 @@
1
+ require 'active_support/core_ext/array/extract_options'
2
+
3
+ class Cell
4
+
5
+ attr_accessor :rules
6
+
7
+ def initialize *args
8
+ self.rules = args.extract_options!
9
+ end
10
+
11
+ end
@@ -4,52 +4,81 @@ module Csv2hash
4
4
  MAPPING = 'mapping'.freeze
5
5
  COLLECTION = 'collection'.freeze
6
6
 
7
- TYPES = [MAPPING, COLLECTION]
7
+ TYPES = [ MAPPING, COLLECTION ]
8
8
 
9
- attr_accessor :rules, :type, :header_size, :structure_rules
9
+ attr_accessor :cells, :structure_rules, :header_size
10
+ attr_reader :type, :name
10
11
 
11
- def initialize rules, type, options = {}
12
- self.rules, self.type = rules, type
13
- self.header_size, self.structure_rules = options.fetch(:header_size) { 0 }, options.fetch(:structure_rules) { {} }
12
+ def initialize name, &blk
13
+ @name = name
14
+ self.cells = []
15
+ self.header_size = 0
16
+ self.structure_rules = {}
17
+ instance_eval(&blk) if block_given?
18
+ end
19
+
20
+ def mapping &blk
21
+ instance_eval(&blk) if block_given?
22
+ end
23
+
24
+ def cell *args
25
+ self.cells << Cell.new(*args)
26
+ end
27
+
28
+ def set_header_size &blk
29
+ self.header_size = yield if block_given?
30
+ end
31
+
32
+ def set_type &blk
33
+ @type = yield if block_given?
34
+ end
35
+
36
+ def set_structure_rules &blk
37
+ self.structure_rules = yield if block_given?
14
38
  end
15
39
 
16
40
  def validate!
17
- unless TYPES.include?(type)
41
+ # binding.pry
42
+ unless TYPES.include?(@type)
18
43
  raise "not suitable type, please use '#{MAPPING}' or '#{COLLECTION}'"
19
44
  end
20
- raise 'rules must be an Array of rules' unless rules.class == Array
21
- raise 'structure rules must be a Hash of rules' unless structure_rules.class == Hash
45
+ raise 'cells must be an Array of cell' unless self.cells.class == Array
46
+ raise 'structure rules must be a Hash of rules' unless self.structure_rules.class == Hash
22
47
  end
23
48
 
24
49
  def default!
25
- rules.each do |rule|
26
- default_position rule
27
- unless rule.has_key? :message
28
- if rule.has_key? :values
29
- rule.merge! message: ':key not supported, please use one of :values'
50
+ # binding.pry
51
+ cells.each do |cell|
52
+ cell.rules.fetch(:position)
53
+
54
+ default_position cell
55
+ unless cell.rules.has_key? :message
56
+ if cell.rules.has_key? :values
57
+ cell.rules.merge! message: ':key not supported, please use one of :values'
30
58
  else
31
- rule.merge! message: 'undefined :key on :position'
59
+ cell.rules.merge! message: 'undefined :key on :position'
32
60
  end
33
61
  end
34
- rule.merge! mappable: true unless rule.has_key? :mappable
35
- rule.merge! type: 'string' unless rule.has_key? :type
36
- rule.merge! values: nil unless rule.has_key? :values
37
- rule.merge! nested: nil unless rule.has_key? :nested
38
- rule.merge! allow_blank: false unless rule.has_key? :allow_blank
39
- rule.merge! extra_validator: nil unless rule.has_key? :extra_validator
62
+ cell.rules.merge! mappable: true unless cell.rules.has_key? :mappable
63
+ cell.rules.merge! type: 'string' unless cell.rules.has_key? :type
64
+ cell.rules.merge! values: nil unless cell.rules.has_key? :values
65
+ cell.rules.merge! nested: nil unless cell.rules.has_key? :nested
66
+ cell.rules.merge! allow_blank: false unless cell.rules.has_key? :allow_blank
67
+ cell.rules.merge! extra_validator: nil unless cell.rules.has_key? :extra_validator
40
68
  end
69
+ # binding.pry
41
70
  end
42
71
 
43
72
  private
44
73
 
45
- def default_position rule
74
+ def default_position cell
46
75
  case type
47
76
  when MAPPING
48
- y, x = rule.fetch(:position, ['undefined', 'undefined'])
49
- rule.merge! key: "key_#{y}_#{x}" unless rule.has_key? :key
77
+ y, x = cell.rules.fetch(:position, ['undefined', 'undefined'])
78
+ cell.rules.merge! key: "key_#{y}_#{x}" unless cell.rules.has_key? :key
50
79
  when COLLECTION
51
- x = rule.fetch :position
52
- rule.merge! key: "key_undefined_#{x}" unless rule.has_key? :key
80
+ x = cell.rules.fetch :position
81
+ cell.rules.merge! key: "key_undefined_#{x}" unless cell.rules.has_key? :key
53
82
  end
54
83
  end
55
84
 
@@ -0,0 +1,10 @@
1
+ module Csv2hash
2
+ module Expectation
3
+
4
+ def unexpected_line? line, y
5
+ return true if y < definition.header_size
6
+ return true if self.options.fetch(:ignore_blank_line){false} and line.compact.empty?
7
+ end
8
+
9
+ end
10
+ end
@@ -1,31 +1,37 @@
1
- module Csv2hash::Parser::Collection
2
- include Csv2hash::Parser
1
+ require_relative '../expectation'
3
2
 
4
- def fill!
5
- self.data = {}.tap do |data_computed|
6
- data_computed[:data] ||= []
7
- self.data_source.each_with_index do |line, y|
8
- next if y < definition.header_size
9
- next if self.options.fetch(:ignore_blank_line) and line.compact.empty?
10
- data_computed[:data] << {}.tap do |data_parsed|
11
- fill_it data_parsed, line
3
+ module Csv2hash
4
+ module Parser
5
+ module Collection
6
+ include Parser
7
+ include Expectation
8
+
9
+ def fill!
10
+ self.data = {}.tap do |data_computed|
11
+ data_computed[:data] ||= []
12
+ self.data_source.each_with_index do |line, y|
13
+ next if unexpected_line?(line, y)
14
+ data_computed[:data] << {}.tap do |data_parsed|
15
+ fill_it data_parsed, line
16
+ end
17
+ end
12
18
  end
13
19
  end
14
- end
15
- end
16
20
 
17
- def fill_it parsed_data, source_data
18
- definition.rules.each do |rule|
19
- if rule.fetch :mappable
20
- x = rule.fetch :position
21
- if (nested = rule.fetch :nested)
22
- parsed_data[nested] ||= {}
23
- parsed_data[nested][rule.fetch(:key)] = source_data[x]
24
- else
25
- parsed_data[rule.fetch(:key)] = source_data[x]
21
+ def fill_it parsed_data, source_data
22
+ definition.cells.each do |cell|
23
+ if cell.rules.fetch :mappable
24
+ x = cell.rules.fetch :position
25
+ if (nested = cell.rules.fetch :nested)
26
+ parsed_data[nested] ||= {}
27
+ parsed_data[nested][cell.rules.fetch(:key)] = source_data[x]
28
+ else
29
+ parsed_data[cell.rules.fetch(:key)] = source_data[x]
30
+ end
31
+ end
26
32
  end
27
33
  end
34
+
28
35
  end
29
36
  end
30
-
31
37
  end
@@ -11,14 +11,14 @@ module Csv2hash::Parser::Mapping
11
11
  end
12
12
 
13
13
  def fill_it parsed_data, source_data
14
- definition.rules.each do |rule|
15
- if rule.fetch :mappable
16
- y, x = rule.fetch :position
17
- if (nested = rule.fetch :nested)
14
+ definition.cells.each do |cell|
15
+ if cell.rules.fetch :mappable
16
+ y, x = cell.rules.fetch :position
17
+ if (nested = cell.rules.fetch :nested)
18
18
  parsed_data[nested] ||= {}
19
- parsed_data[nested][rule.fetch(:key)] = source_data[y][x]
19
+ parsed_data[nested][cell.rules.fetch(:key)] = source_data[y][x]
20
20
  else
21
- parsed_data[rule.fetch(:key)] = source_data[y][x]
21
+ parsed_data[cell.rules.fetch(:key)] = source_data[y][x]
22
22
  end
23
23
  end
24
24
  end
@@ -0,0 +1,13 @@
1
+ class Registry
2
+ def initialize
3
+ @definitions = Hash.new
4
+ end
5
+
6
+ def [] name
7
+ @definitions[name]
8
+ end
9
+
10
+ def []= name, definition
11
+ @definitions[name] = definition
12
+ end
13
+ end
@@ -4,6 +4,7 @@ module Csv2hash::StructureValidator
4
4
  class ValidationError < StandardError ; end
5
5
 
6
6
  def validate_structure!
7
+ # binding.pry
7
8
  definition.structure_rules.each do |rule, options|
8
9
  begin
9
10
  rule_instance(rule, options).validate! data_source
@@ -1,18 +1,24 @@
1
- module Csv2hash::Validator::Collection
2
- include Csv2hash::Validator
1
+ require_relative '../expectation'
3
2
 
4
- def validate_data!
5
- self.data_source.each_with_index do |line, y|
6
- next if y < definition.header_size
7
- next if self.options.fetch(:ignore_blank_line) and line.compact.empty?
8
- validate_rules y
9
- end
10
- end
3
+ module Csv2hash
4
+ module Validator
5
+ module Collection
6
+ include Validator
7
+ include Expectation
11
8
 
12
- protected
9
+ def validate_data!
10
+ self.data_source.each_with_index do |line, y|
11
+ next if unexpected_line?(line, y)
12
+ validate_rules y
13
+ end
14
+ end
13
15
 
14
- def position _position
15
- [nil, _position]
16
- end
16
+ protected
17
17
 
18
+ def position _position
19
+ [nil, _position]
20
+ end
21
+
22
+ end
23
+ end
18
24
  end
@@ -1,14 +1,18 @@
1
- module Csv2hash::Validator::Mapping
2
- include Csv2hash::Validator
1
+ module Csv2hash
2
+ module Validator
3
+ module Mapping
4
+ include Validator
3
5
 
4
- def validate_data!
5
- validate_rules data_source
6
- end
6
+ def validate_data!
7
+ validate_rules data_source
8
+ end
7
9
 
8
- protected
10
+ protected
9
11
 
10
- def position _position
11
- _position
12
- end
12
+ def position _position
13
+ _position
14
+ end
13
15
 
16
+ end
17
+ end
14
18
  end
@@ -2,12 +2,13 @@ module Csv2hash
2
2
  module Validator
3
3
 
4
4
  def validate_rules y=nil
5
- definition.rules.each do |rule|
6
- _y, x = position rule.fetch(:position)
5
+ # binding.pry
6
+ definition.cells.each do |cell|
7
+ _y, x = position cell.rules.fetch(:position)
7
8
  begin
8
- validate_cell (_y||y), x, rule
9
+ validate_cell (_y||y), x, cell
9
10
  rescue => e
10
- self.errors << { y: (_y||y), x: x, message: e.message, key: rule.fetch(:key) }
11
+ self.errors << { y: (_y||y), x: x, message: e.message, key: cell.rules.fetch(:key) }
11
12
  raise if break_on_failure
12
13
  end
13
14
  end
@@ -17,14 +18,14 @@ module Csv2hash
17
18
 
18
19
  protected
19
20
 
20
- def validate_cell y, x, rule
21
+ def validate_cell y, x, cell
21
22
  value = data_source[y][x] rescue nil
22
23
  begin
23
- raise unless value unless rule.fetch :allow_blank
24
- if (extra_validator = rule.fetch :extra_validator) && extra_validator.kind_of?(Csv2hash::ExtraValidator)
25
- raise unless extra_validator.valid? rule, value
24
+ raise unless value unless cell.rules.fetch :allow_blank
25
+ if (extra_validator = cell.rules.fetch :extra_validator) && extra_validator.kind_of?(Csv2hash::ExtraValidator)
26
+ raise unless extra_validator.valid? cell.rules, value
26
27
  else
27
- if value && (values = rule.fetch :values)
28
+ if value && (values = cell.rules.fetch :values)
28
29
  if values.class == Range
29
30
  raise unless values.include?(value.to_f)
30
31
  else
@@ -33,13 +34,13 @@ module Csv2hash
33
34
  end
34
35
  end
35
36
  rescue => e
36
- raise message(rule, y, x)
37
+ raise message(cell, y, x)
37
38
  end
38
39
  end
39
40
 
40
- def message rule, y, x
41
- msg = rule.fetch(:message).tap do |msg|
42
- rule.each { |key, value| msg.gsub!(":#{key.to_s}", value.to_s) unless key == :position }
41
+ def message cell, y, x
42
+ msg = cell.rules.fetch(:message).tap do |msg|
43
+ cell.rules.each { |key, value| msg.gsub!(":#{key.to_s}", value.to_s) unless key == :position }
43
44
  end
44
45
  msg.gsub ':position', "[#{y}, #{x}]"
45
46
  end
@@ -1,3 +1,3 @@
1
1
  module Csv2hash
2
- VERSION = '0.5.0'
2
+ VERSION = '0.6.0'
3
3
  end
data/lib/csv2hash.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require_relative 'csv2hash/version'
2
+ require_relative 'csv2hash/registry'
3
+ require_relative 'csv2hash/cell'
2
4
  require_relative 'csv2hash/definition'
3
5
  require_relative 'csv2hash/validator'
4
6
  require_relative 'csv2hash/validator/mapping'
@@ -26,6 +28,24 @@ module Csv2hash
26
28
  class Main
27
29
  include Csv2hash::StructureValidator
28
30
 
31
+ class << self
32
+
33
+ def generate_definition name, &block
34
+ definition = Definition.new name, &block
35
+ Main[name] = definition
36
+ end
37
+
38
+ def [] definition_name
39
+ @@registry[definition_name]
40
+ end
41
+
42
+ def []= definition_name, role
43
+ @@registry[definition_name] = role
44
+ end
45
+ end
46
+
47
+ @@registry = Registry.new
48
+
29
49
  attr_accessor :definition, :file_path_or_data, :data, :notifier, :break_on_failure, :errors, :options
30
50
 
31
51
  def initialize definition, file_path_or_data, *args