csv_decision 0.0.9 → 0.1.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 (58) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/README.md +1 -1
  4. data/benchmarks/rufus_decision.rb +3 -5
  5. data/csv_decision.gemspec +1 -3
  6. data/doc/CSVDecision/CellValidationError.html +1 -1
  7. data/doc/CSVDecision/Columns/Dictionary.html +112 -18
  8. data/doc/CSVDecision/Columns.html +112 -81
  9. data/doc/CSVDecision/Data.html +1 -1
  10. data/doc/CSVDecision/Decide.html +1 -1
  11. data/doc/CSVDecision/Decision.html +1 -1
  12. data/doc/CSVDecision/Dictionary/Entry.html +1 -1
  13. data/doc/CSVDecision/Dictionary.html +152 -7
  14. data/doc/CSVDecision/Error.html +1 -1
  15. data/doc/CSVDecision/FileError.html +1 -1
  16. data/doc/CSVDecision/Header.html +1 -1
  17. data/doc/CSVDecision/Input.html +5 -11
  18. data/doc/CSVDecision/Load.html +1 -1
  19. data/doc/CSVDecision/Matchers/Constant.html +1 -1
  20. data/doc/CSVDecision/Matchers/Function.html +1 -1
  21. data/doc/CSVDecision/Matchers/Guard.html +23 -23
  22. data/doc/CSVDecision/Matchers/Matcher.html +13 -13
  23. data/doc/CSVDecision/Matchers/Numeric.html +3 -3
  24. data/doc/CSVDecision/Matchers/Pattern.html +9 -11
  25. data/doc/CSVDecision/Matchers/Proc.html +571 -0
  26. data/doc/CSVDecision/Matchers/Range.html +1 -1
  27. data/doc/CSVDecision/Matchers/Symbol.html +1 -1
  28. data/doc/CSVDecision/Matchers.html +63 -83
  29. data/doc/CSVDecision/Options.html +1 -1
  30. data/doc/CSVDecision/Parse.html +115 -8
  31. data/doc/CSVDecision/Result.html +55 -37
  32. data/doc/CSVDecision/ScanRow.html +3 -3
  33. data/doc/CSVDecision/Table.html +5 -6
  34. data/doc/CSVDecision.html +5 -5
  35. data/doc/_index.html +12 -5
  36. data/doc/class_list.html +1 -1
  37. data/doc/file.README.html +2 -2
  38. data/doc/index.html +2 -2
  39. data/doc/method_list.html +110 -46
  40. data/doc/top-level-namespace.html +1 -1
  41. data/lib/csv_decision/columns.rb +14 -9
  42. data/lib/csv_decision/dictionary.rb +46 -21
  43. data/lib/csv_decision/input.rb +13 -6
  44. data/lib/csv_decision/matchers/constant.rb +1 -1
  45. data/lib/csv_decision/matchers/guard.rb +7 -10
  46. data/lib/csv_decision/matchers/numeric.rb +2 -2
  47. data/lib/csv_decision/matchers/pattern.rb +1 -2
  48. data/lib/csv_decision/matchers/range.rb +1 -1
  49. data/lib/csv_decision/matchers/symbol.rb +1 -1
  50. data/lib/csv_decision/matchers.rb +38 -4
  51. data/lib/csv_decision/parse.rb +100 -5
  52. data/lib/csv_decision/result.rb +23 -7
  53. data/lib/csv_decision/table.rb +2 -2
  54. data/spec/csv_decision/columns_spec.rb +89 -0
  55. data/spec/csv_decision/examples_spec.rb +23 -1
  56. data/spec/csv_decision/input_spec.rb +0 -2
  57. data/spec/csv_decision/table_spec.rb +1 -1
  58. metadata +3 -30
data/doc/method_list.html CHANGED
@@ -53,6 +53,14 @@
53
53
 
54
54
 
55
55
  <li class="even ">
56
+ <div class="item">
57
+ <span class='object_link'><a href="CSVDecision/Dictionary.html#add_name-class_method" title="CSVDecision::Dictionary.add_name (method)">add_name</a></span>
58
+ <small>CSVDecision::Dictionary</small>
59
+ </div>
60
+ </li>
61
+
62
+
63
+ <li class="odd ">
56
64
  <div class="item">
57
65
  <span class='object_link'><a href="CSVDecision/Result.html#add_outs-instance_method" title="CSVDecision::Result#add_outs (method)">#add_outs</a></span>
58
66
  <small>CSVDecision::Result</small>
@@ -60,7 +68,7 @@
60
68
  </li>
61
69
 
62
70
 
63
- <li class="odd ">
71
+ <li class="even ">
64
72
  <div class="item">
65
73
  <span class='object_link'><a href="CSVDecision/Result.html#attributes-instance_method" title="CSVDecision::Result#attributes (method)">#attributes</a></span>
66
74
  <small>CSVDecision::Result</small>
@@ -68,7 +76,7 @@
68
76
  </li>
69
77
 
70
78
 
71
- <li class="even ">
79
+ <li class="odd ">
72
80
  <div class="item">
73
81
  <span class='object_link'><a href="CSVDecision/Dictionary.html#build-class_method" title="CSVDecision::Dictionary.build (method)">build</a></span>
74
82
  <small>CSVDecision::Dictionary</small>
@@ -76,7 +84,7 @@
76
84
  </li>
77
85
 
78
86
 
79
- <li class="odd ">
87
+ <li class="even ">
80
88
  <div class="item">
81
89
  <span class='object_link'><a href="CSVDecision/Table.html#columns-instance_method" title="CSVDecision::Table#columns (method)">#columns</a></span>
82
90
  <small>CSVDecision::Table</small>
@@ -84,6 +92,14 @@
84
92
  </li>
85
93
 
86
94
 
95
+ <li class="odd ">
96
+ <div class="item">
97
+ <span class='object_link'><a href="CSVDecision/Columns/Dictionary.html#columns-instance_method" title="CSVDecision::Columns::Dictionary#columns (method)">#columns</a></span>
98
+ <small>CSVDecision::Columns::Dictionary</small>
99
+ </div>
100
+ </li>
101
+
102
+
87
103
  <li class="even ">
88
104
  <div class="item">
89
105
  <span class='object_link'><a href="CSVDecision/ScanRow.html#constants-instance_method" title="CSVDecision::ScanRow#constants (method)">#constants</a></span>
@@ -189,6 +205,14 @@
189
205
 
190
206
 
191
207
  <li class="odd ">
208
+ <div class="item">
209
+ <span class='object_link'><a href="CSVDecision/Matchers/Proc.html#function-instance_method" title="CSVDecision::Matchers::Proc#function (method)">#function</a></span>
210
+ <small>CSVDecision::Matchers::Proc</small>
211
+ </div>
212
+ </li>
213
+
214
+
215
+ <li class="even ">
192
216
  <div class="item">
193
217
  <span class='object_link'><a href="CSVDecision/Table.html#if_rows-instance_method" title="CSVDecision::Table#if_rows (method)">#if_rows</a></span>
194
218
  <small>CSVDecision::Table</small>
@@ -196,7 +220,7 @@
196
220
  </li>
197
221
 
198
222
 
199
- <li class="even ">
223
+ <li class="odd ">
200
224
  <div class="item">
201
225
  <span class='object_link'><a href="CSVDecision/Columns.html#ifs-instance_method" title="CSVDecision::Columns#ifs (method)">#ifs</a></span>
202
226
  <small>CSVDecision::Columns</small>
@@ -204,7 +228,7 @@
204
228
  </li>
205
229
 
206
230
 
207
- <li class="odd ">
231
+ <li class="even ">
208
232
  <div class="item">
209
233
  <span class='object_link'><a href="CSVDecision/Columns/Dictionary.html#ifs-instance_method" title="CSVDecision::Columns::Dictionary#ifs (method)">#ifs</a></span>
210
234
  <small>CSVDecision::Columns::Dictionary</small>
@@ -212,34 +236,42 @@
212
236
  </li>
213
237
 
214
238
 
239
+ <li class="odd ">
240
+ <div class="item">
241
+ <span class='object_link'><a href="CSVDecision/Matchers/Proc.html#initialize-instance_method" title="CSVDecision::Matchers::Proc#initialize (method)">#initialize</a></span>
242
+ <small>CSVDecision::Matchers::Proc</small>
243
+ </div>
244
+ </li>
245
+
246
+
215
247
  <li class="even ">
216
248
  <div class="item">
217
- <span class='object_link'><a href="CSVDecision/Matchers/Function.html#initialize-instance_method" title="CSVDecision::Matchers::Function#initialize (method)">#initialize</a></span>
218
- <small>CSVDecision::Matchers::Function</small>
249
+ <span class='object_link'><a href="CSVDecision/Table.html#initialize-instance_method" title="CSVDecision::Table#initialize (method)">#initialize</a></span>
250
+ <small>CSVDecision::Table</small>
219
251
  </div>
220
252
  </li>
221
253
 
222
254
 
223
255
  <li class="odd ">
224
256
  <div class="item">
225
- <span class='object_link'><a href="CSVDecision/Matchers/Matcher.html#initialize-instance_method" title="CSVDecision::Matchers::Matcher#initialize (method)">#initialize</a></span>
226
- <small>CSVDecision::Matchers::Matcher</small>
257
+ <span class='object_link'><a href="CSVDecision/Matchers/Function.html#initialize-instance_method" title="CSVDecision::Matchers::Function#initialize (method)">#initialize</a></span>
258
+ <small>CSVDecision::Matchers::Function</small>
227
259
  </div>
228
260
  </li>
229
261
 
230
262
 
231
263
  <li class="even ">
232
264
  <div class="item">
233
- <span class='object_link'><a href="CSVDecision/Matchers.html#initialize-instance_method" title="CSVDecision::Matchers#initialize (method)">#initialize</a></span>
234
- <small>CSVDecision::Matchers</small>
265
+ <span class='object_link'><a href="CSVDecision/Matchers/Matcher.html#initialize-instance_method" title="CSVDecision::Matchers::Matcher#initialize (method)">#initialize</a></span>
266
+ <small>CSVDecision::Matchers::Matcher</small>
235
267
  </div>
236
268
  </li>
237
269
 
238
270
 
239
271
  <li class="odd ">
240
272
  <div class="item">
241
- <span class='object_link'><a href="CSVDecision/ScanRow.html#initialize-instance_method" title="CSVDecision::ScanRow#initialize (method)">#initialize</a></span>
242
- <small>CSVDecision::ScanRow</small>
273
+ <span class='object_link'><a href="CSVDecision/Matchers.html#initialize-instance_method" title="CSVDecision::Matchers#initialize (method)">#initialize</a></span>
274
+ <small>CSVDecision::Matchers</small>
243
275
  </div>
244
276
  </li>
245
277
 
@@ -262,32 +294,32 @@
262
294
 
263
295
  <li class="even ">
264
296
  <div class="item">
265
- <span class='object_link'><a href="CSVDecision/Decision.html#initialize-instance_method" title="CSVDecision::Decision#initialize (method)">#initialize</a></span>
266
- <small>CSVDecision::Decision</small>
297
+ <span class='object_link'><a href="CSVDecision/Columns/Dictionary.html#initialize-instance_method" title="CSVDecision::Columns::Dictionary#initialize (method)">#initialize</a></span>
298
+ <small>CSVDecision::Columns::Dictionary</small>
267
299
  </div>
268
300
  </li>
269
301
 
270
302
 
271
303
  <li class="odd ">
272
304
  <div class="item">
273
- <span class='object_link'><a href="CSVDecision/Columns.html#initialize-instance_method" title="CSVDecision::Columns#initialize (method)">#initialize</a></span>
274
- <small>CSVDecision::Columns</small>
305
+ <span class='object_link'><a href="CSVDecision/Decision.html#initialize-instance_method" title="CSVDecision::Decision#initialize (method)">#initialize</a></span>
306
+ <small>CSVDecision::Decision</small>
275
307
  </div>
276
308
  </li>
277
309
 
278
310
 
279
311
  <li class="even ">
280
312
  <div class="item">
281
- <span class='object_link'><a href="CSVDecision/Columns/Dictionary.html#initialize-instance_method" title="CSVDecision::Columns::Dictionary#initialize (method)">#initialize</a></span>
282
- <small>CSVDecision::Columns::Dictionary</small>
313
+ <span class='object_link'><a href="CSVDecision/Columns.html#initialize-instance_method" title="CSVDecision::Columns#initialize (method)">#initialize</a></span>
314
+ <small>CSVDecision::Columns</small>
283
315
  </div>
284
316
  </li>
285
317
 
286
318
 
287
319
  <li class="odd ">
288
320
  <div class="item">
289
- <span class='object_link'><a href="CSVDecision/Table.html#initialize-instance_method" title="CSVDecision::Table#initialize (method)">#initialize</a></span>
290
- <small>CSVDecision::Table</small>
321
+ <span class='object_link'><a href="CSVDecision/ScanRow.html#initialize-instance_method" title="CSVDecision::ScanRow#initialize (method)">#initialize</a></span>
322
+ <small>CSVDecision::ScanRow</small>
291
323
  </div>
292
324
  </li>
293
325
 
@@ -302,8 +334,8 @@
302
334
 
303
335
  <li class="odd ">
304
336
  <div class="item">
305
- <span class='object_link'><a href="CSVDecision/Matchers.html#ins-instance_method" title="CSVDecision::Matchers#ins (method)">#ins</a></span>
306
- <small>CSVDecision::Matchers</small>
337
+ <span class='object_link'><a href="CSVDecision/Columns.html#input_keys-instance_method" title="CSVDecision::Columns#input_keys (method)">#input_keys</a></span>
338
+ <small>CSVDecision::Columns</small>
307
339
  </div>
308
340
  </li>
309
341
 
@@ -325,6 +357,14 @@
325
357
 
326
358
 
327
359
  <li class="even ">
360
+ <div class="item">
361
+ <span class='object_link'><a href="CSVDecision/Matchers.html#ins-instance_method" title="CSVDecision::Matchers#ins (method)">#ins</a></span>
362
+ <small>CSVDecision::Matchers</small>
363
+ </div>
364
+ </li>
365
+
366
+
367
+ <li class="odd ">
328
368
  <div class="item">
329
369
  <span class='object_link'><a href="CSVDecision/Dictionary/Entry.html#ins%3F-instance_method" title="CSVDecision::Dictionary::Entry#ins? (method)">#ins?</a></span>
330
370
  <small>CSVDecision::Dictionary::Entry</small>
@@ -332,7 +372,7 @@
332
372
  </li>
333
373
 
334
374
 
335
- <li class="odd ">
375
+ <li class="even ">
336
376
  <div class="item">
337
377
  <span class='object_link'><a href="CSVDecision/Matchers/Matcher.html#ins%3F-instance_method" title="CSVDecision::Matchers::Matcher#ins? (method)">#ins?</a></span>
338
378
  <small>CSVDecision::Matchers::Matcher</small>
@@ -340,6 +380,14 @@
340
380
  </li>
341
381
 
342
382
 
383
+ <li class="odd ">
384
+ <div class="item">
385
+ <span class='object_link'><a href="CSVDecision/Parse.html#invalid_out_ref%3F-class_method" title="CSVDecision::Parse.invalid_out_ref? (method)">invalid_out_ref?</a></span>
386
+ <small>CSVDecision::Parse</small>
387
+ </div>
388
+ </li>
389
+
390
+
343
391
  <li class="even ">
344
392
  <div class="item">
345
393
  <span class='object_link'><a href="CSVDecision.html#load-class_method" title="CSVDecision.load (method)">load</a></span>
@@ -550,48 +598,48 @@
550
598
 
551
599
  <li class="even ">
552
600
  <div class="item">
553
- <span class='object_link'><a href="CSVDecision/Columns.html#outs-instance_method" title="CSVDecision::Columns#outs (method)">#outs</a></span>
554
- <small>CSVDecision::Columns</small>
601
+ <span class='object_link'><a href="CSVDecision/Matchers.html#outs-instance_method" title="CSVDecision::Matchers#outs (method)">#outs</a></span>
602
+ <small>CSVDecision::Matchers</small>
555
603
  </div>
556
604
  </li>
557
605
 
558
606
 
559
607
  <li class="odd ">
560
608
  <div class="item">
561
- <span class='object_link'><a href="CSVDecision/Matchers.html#outs-instance_method" title="CSVDecision::Matchers#outs (method)">#outs</a></span>
562
- <small>CSVDecision::Matchers</small>
609
+ <span class='object_link'><a href="CSVDecision/Columns/Dictionary.html#outs-instance_method" title="CSVDecision::Columns::Dictionary#outs (method)">#outs</a></span>
610
+ <small>CSVDecision::Columns::Dictionary</small>
563
611
  </div>
564
612
  </li>
565
613
 
566
614
 
567
615
  <li class="even ">
568
616
  <div class="item">
569
- <span class='object_link'><a href="CSVDecision/Columns/Dictionary.html#outs-instance_method" title="CSVDecision::Columns::Dictionary#outs (method)">#outs</a></span>
570
- <small>CSVDecision::Columns::Dictionary</small>
617
+ <span class='object_link'><a href="CSVDecision/Columns.html#outs-instance_method" title="CSVDecision::Columns#outs (method)">#outs</a></span>
618
+ <small>CSVDecision::Columns</small>
571
619
  </div>
572
620
  </li>
573
621
 
574
622
 
575
623
  <li class="odd ">
576
624
  <div class="item">
577
- <span class='object_link'><a href="CSVDecision/Matchers/Guard.html#outs%3F-instance_method" title="CSVDecision::Matchers::Guard#outs? (method)">#outs?</a></span>
578
- <small>CSVDecision::Matchers::Guard</small>
625
+ <span class='object_link'><a href="CSVDecision/Matchers/Constant.html#outs%3F-instance_method" title="CSVDecision::Matchers::Constant#outs? (method)">#outs?</a></span>
626
+ <small>CSVDecision::Matchers::Constant</small>
579
627
  </div>
580
628
  </li>
581
629
 
582
630
 
583
631
  <li class="even ">
584
632
  <div class="item">
585
- <span class='object_link'><a href="CSVDecision/Matchers/Matcher.html#outs%3F-instance_method" title="CSVDecision::Matchers::Matcher#outs? (method)">#outs?</a></span>
586
- <small>CSVDecision::Matchers::Matcher</small>
633
+ <span class='object_link'><a href="CSVDecision/Matchers/Guard.html#outs%3F-instance_method" title="CSVDecision::Matchers::Guard#outs? (method)">#outs?</a></span>
634
+ <small>CSVDecision::Matchers::Guard</small>
587
635
  </div>
588
636
  </li>
589
637
 
590
638
 
591
639
  <li class="odd ">
592
640
  <div class="item">
593
- <span class='object_link'><a href="CSVDecision/Matchers/Constant.html#outs%3F-instance_method" title="CSVDecision::Matchers::Constant#outs? (method)">#outs?</a></span>
594
- <small>CSVDecision::Matchers::Constant</small>
641
+ <span class='object_link'><a href="CSVDecision/Matchers/Matcher.html#outs%3F-instance_method" title="CSVDecision::Matchers::Matcher#outs? (method)">#outs?</a></span>
642
+ <small>CSVDecision::Matchers::Matcher</small>
595
643
  </div>
596
644
  </li>
597
645
 
@@ -614,16 +662,16 @@
614
662
 
615
663
  <li class="even ">
616
664
  <div class="item">
617
- <span class='object_link'><a href="CSVDecision/Matchers.html#parse-class_method" title="CSVDecision::Matchers.parse (method)">parse</a></span>
618
- <small>CSVDecision::Matchers</small>
665
+ <span class='object_link'><a href="CSVDecision.html#parse-class_method" title="CSVDecision.parse (method)">parse</a></span>
666
+ <small>CSVDecision</small>
619
667
  </div>
620
668
  </li>
621
669
 
622
670
 
623
671
  <li class="odd ">
624
672
  <div class="item">
625
- <span class='object_link'><a href="CSVDecision.html#parse-class_method" title="CSVDecision.parse (method)">parse</a></span>
626
- <small>CSVDecision</small>
673
+ <span class='object_link'><a href="CSVDecision/Matchers.html#parse-class_method" title="CSVDecision::Matchers.parse (method)">parse</a></span>
674
+ <small>CSVDecision::Matchers</small>
627
675
  </div>
628
676
  </li>
629
677
 
@@ -710,16 +758,16 @@
710
758
 
711
759
  <li class="even ">
712
760
  <div class="item">
713
- <span class='object_link'><a href="CSVDecision/ScanRow.html#scan-class_method" title="CSVDecision::ScanRow.scan (method)">scan</a></span>
714
- <small>CSVDecision::ScanRow</small>
761
+ <span class='object_link'><a href="CSVDecision/Decision.html#scan-instance_method" title="CSVDecision::Decision#scan (method)">#scan</a></span>
762
+ <small>CSVDecision::Decision</small>
715
763
  </div>
716
764
  </li>
717
765
 
718
766
 
719
767
  <li class="odd ">
720
768
  <div class="item">
721
- <span class='object_link'><a href="CSVDecision/Decision.html#scan-instance_method" title="CSVDecision::Decision#scan (method)">#scan</a></span>
722
- <small>CSVDecision::Decision</small>
769
+ <span class='object_link'><a href="CSVDecision/ScanRow.html#scan-class_method" title="CSVDecision::ScanRow.scan (method)">scan</a></span>
770
+ <small>CSVDecision::ScanRow</small>
723
771
  </div>
724
772
  </li>
725
773
 
@@ -765,6 +813,14 @@
765
813
 
766
814
 
767
815
  <li class="odd ">
816
+ <div class="item">
817
+ <span class='object_link'><a href="CSVDecision/Matchers/Proc.html#symbols-instance_method" title="CSVDecision::Matchers::Proc#symbols (method)">#symbols</a></span>
818
+ <small>CSVDecision::Matchers::Proc</small>
819
+ </div>
820
+ </li>
821
+
822
+
823
+ <li class="even ">
768
824
  <div class="item">
769
825
  <span class='object_link'><a href="CSVDecision/Parse.html#table-class_method" title="CSVDecision::Parse.table (method)">table</a></span>
770
826
  <small>CSVDecision::Parse</small>
@@ -772,7 +828,7 @@
772
828
  </li>
773
829
 
774
830
 
775
- <li class="even ">
831
+ <li class="odd ">
776
832
  <div class="item">
777
833
  <span class='object_link'><a href="CSVDecision/Data.html#to_array-class_method" title="CSVDecision::Data.to_array (method)">to_array</a></span>
778
834
  <small>CSVDecision::Data</small>
@@ -780,7 +836,7 @@
780
836
  </li>
781
837
 
782
838
 
783
- <li class="odd ">
839
+ <li class="even ">
784
840
  <div class="item">
785
841
  <span class='object_link'><a href="CSVDecision/Matchers.html#to_numeric-class_method" title="CSVDecision::Matchers.to_numeric (method)">to_numeric</a></span>
786
842
  <small>CSVDecision::Matchers</small>
@@ -788,6 +844,14 @@
788
844
  </li>
789
845
 
790
846
 
847
+ <li class="odd ">
848
+ <div class="item">
849
+ <span class='object_link'><a href="CSVDecision/Matchers/Proc.html#type-instance_method" title="CSVDecision::Matchers::Proc#type (method)">#type</a></span>
850
+ <small>CSVDecision::Matchers::Proc</small>
851
+ </div>
852
+ </li>
853
+
854
+
791
855
  <li class="even ">
792
856
  <div class="item">
793
857
  <span class='object_link'><a href="CSVDecision/Dictionary/Entry.html#type-instance_method" title="CSVDecision::Dictionary::Entry#type (method)">#type</a></span>
@@ -100,7 +100,7 @@
100
100
  </div>
101
101
 
102
102
  <div id="footer">
103
- Generated on Fri Jan 5 21:43:59 2018 by
103
+ Generated on Sat Jan 6 20:03:01 2018 by
104
104
  <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
105
105
  0.9.12 (ruby-2.4.0).
106
106
  </div>
@@ -15,15 +15,15 @@ module CSVDecision
15
15
  # The key of each hash is the header cell's array column index.
16
16
  # Note that input and output columns can be interspersed and need not have unique names.
17
17
  class Dictionary
18
- # Input columns.
18
+ # @return [Hash{Integer=>Entry}] All column names.
19
+ attr_accessor :columns
20
+
19
21
  # @return [Hash{Integer=>Entry}] All input column dictionary entries.
20
22
  attr_accessor :ins
21
23
 
22
- # Output columns.
23
24
  # @return [Hash{Integer=>Entry}] All output column dictionary entries.
24
25
  attr_accessor :outs
25
26
 
26
- # if: columns.
27
27
  # @return [Hash{Integer=>Entry}] All if: column dictionary entries.
28
28
  attr_accessor :ifs
29
29
 
@@ -34,18 +34,15 @@ module CSVDecision
34
34
  # attr_accessor :defaults
35
35
 
36
36
  def initialize
37
+ @columns = {}
38
+ @ifs = {}
37
39
  @ins = {}
38
40
  @outs = {}
39
- @ifs = {}
40
41
  # TODO: @path = {}
41
42
  # TODO: @defaults = {}
42
43
  end
43
44
  end
44
45
 
45
- # Dictionary of all data columns.
46
- # @return [Columns::Dictionary]
47
- attr_reader :dictionary
48
-
49
46
  # Input columns hash keyed by column index.
50
47
  # @return [Hash{Index=>Entry}]
51
48
  def ins
@@ -55,7 +52,7 @@ module CSVDecision
55
52
  # Output columns hash keyed by column index.
56
53
  # @return [Hash{Index=>Entry}]
57
54
  def outs
58
- @dictionary.outs
55
+ @dictionary&.outs
59
56
  end
60
57
 
61
58
  # if: columns hash keyed by column index.
@@ -64,6 +61,14 @@ module CSVDecision
64
61
  @dictionary.ifs
65
62
  end
66
63
 
64
+ def dictionary
65
+ @dictionary.columns
66
+ end
67
+
68
+ def input_keys
69
+ @dictionary.columns.select { |_k, v| v == :in }.keys
70
+ end
71
+
67
72
  # Input columns with defaults specified (planned feature)
68
73
  # def defaults
69
74
  # @dictionary.defaults
@@ -26,9 +26,7 @@ module CSVDecision
26
26
  end
27
27
  end
28
28
 
29
- # TODO: implement all anonymous column types
30
- # COLUMN_TYPE_ANONYMOUS = Set.new(%i[path if guard]).freeze
31
- # These column types do not need a name
29
+ # These column types do not need a name.
32
30
  COLUMN_TYPE_ANONYMOUS = Set.new(%i[guard if]).freeze
33
31
  private_constant :COLUMN_TYPE_ANONYMOUS
34
32
 
@@ -42,27 +40,21 @@ module CSVDecision
42
40
  dictionary = parse_cell(cell: cell, index: index, dictionary: dictionary)
43
41
  end
44
42
 
45
- validate(dictionary)
46
- end
47
-
48
- def self.validate(dictionary)
49
- dictionary.outs.each_pair do |col, column|
50
- validate_out(dictionary: dictionary, column_name: column.name, col: col)
51
- end
52
-
53
43
  dictionary
54
44
  end
55
- private_class_method :validate
56
-
57
- def self.validate_out(dictionary:, column_name:, col:)
58
- if dictionary.ins.any? { |_, column| column_name == column.name }
59
- raise CellValidationError, "output column name '#{column_name}' is also an input column"
60
- end
61
45
 
62
- return unless dictionary.outs.any? { |key, column| column_name == column.name && col != key }
63
- raise CellValidationError, "output column name '#{column_name}' is duplicated"
46
+ # Add a new symbol to the dictionary of named input and output columns.
47
+ #
48
+ # @param columns [{Symbol=>Symbol}] Hash of column names with key values :in or :out.
49
+ # @param name [Symbol] Symbolized column name.
50
+ # @param out [false, Index] False if an input column, otherwise the index of the output column.
51
+ # @return [{Symbol=>Symbol}] Column dictionary updated with the new name.
52
+ def self.add_name(columns:, name:, out: false)
53
+ validate_name(columns: columns, name: name, out: out)
54
+
55
+ columns[name] = out ? out : :in
56
+ columns
64
57
  end
65
- private_class_method :validate_out
66
58
 
67
59
  def self.validate_column(cell:, index:)
68
60
  match = Header::COLUMN_TYPE.match(cell)
@@ -124,12 +116,20 @@ module CSVDecision
124
116
  # # Treat set: as an in: column
125
117
  # dictionary.ins[index] = entry
126
118
 
127
- when :in, :guard
119
+ when :in
120
+ add_name(columns: dictionary.columns, name: entry.name)
121
+ dictionary.ins[index] = entry
122
+
123
+ # A guard column is still added to the ins hash for parsing as an input column.
124
+ when :guard
128
125
  dictionary.ins[index] = entry
129
126
 
130
127
  when :out
128
+ add_name(columns: dictionary.columns, name: entry.name, out: index)
131
129
  dictionary.outs[index] = entry
132
130
 
131
+ # Add an if: column to both the +outs+ hash for output column parsing, and also
132
+ # a specialized +ifs+ hash used for evaluating them for row filtering.
133
133
  when :if
134
134
  dictionary.outs[index] = entry
135
135
  dictionary.ifs[index] = entry
@@ -139,6 +139,31 @@ module CSVDecision
139
139
  end
140
140
  private_class_method :dictionary_entry
141
141
 
142
+ def self.validate_name(columns:, name:, out:)
143
+ return unless (in_out = columns[name])
144
+
145
+ return validate_out_name(in_out: in_out, name: name) if out
146
+ validate_in_name(in_out: in_out, name: name)
147
+ end
148
+ private_class_method :validate_name
149
+
150
+ def self.validate_out_name(in_out:, name:)
151
+ if in_out == :in
152
+ raise CellValidationError, "output column name '#{name}' is also an input column"
153
+ end
154
+
155
+ raise CellValidationError, "output column name '#{name}' is duplicated"
156
+ end
157
+ private_class_method :validate_out_name
158
+
159
+ def self.validate_in_name(in_out:, name:)
160
+ # in: columns may be duped
161
+ return if in_out == :in
162
+
163
+ raise CellValidationError, "output column name '#{name}' is also an input column"
164
+ end
165
+ private_class_method :validate_in_name
166
+
142
167
  # def self.default_if(type)
143
168
  # return nil if type == :set
144
169
  # return :nil? if type == :'set/nil'
@@ -17,18 +17,25 @@ module CSVDecision
17
17
  def self.parse(table:, input:, symbolize_keys:)
18
18
  validate(input)
19
19
 
20
- # For safety the default is to symbolize keys and make a copy of the hash.
21
- # However, if this is turned off then the keys must already symbolized.
22
- input = symbolize_keys ? input.symbolize_keys : input
20
+ parsed_input =
21
+ parse_input(table: table, input: input(table, input, symbolize_keys))
23
22
 
24
- parsed_input = parse_input(table: table, input: input)
25
-
26
- # Freeze the copy of the input hash we just created.
23
+ # We can freeze it as we made our own copy
27
24
  parsed_input[:hash].freeze if symbolize_keys
28
25
 
29
26
  parsed_input.freeze
30
27
  end
31
28
 
29
+ def self.input(table, input, symbolize_keys)
30
+ return input unless symbolize_keys
31
+
32
+ # For safety the default is to symbolize the keys of a copy of the input hash.
33
+ input = input.symbolize_keys
34
+ input.slice!(*table.columns.input_keys)
35
+ input
36
+ end
37
+ private_class_method :input
38
+
32
39
  def self.validate(input)
33
40
  return if input.is_a?(Hash) && !input.empty?
34
41
  raise ArgumentError, 'input must be a non-empty hash'
@@ -38,7 +38,7 @@ module CSVDecision
38
38
  end
39
39
 
40
40
  def self.proc(function:)
41
- Matchers::Proc.with(type: :constant, function: function)
41
+ Matchers::Proc.new(type: :constant, function: function)
42
42
  end
43
43
  private_class_method :proc
44
44
 
@@ -12,21 +12,17 @@ module CSVDecision
12
12
  # e.g., +>:column.present?+ or +:column == 100.0+.
13
13
  class Guard < Matcher
14
14
  # Column symbol expression - e.g., +>:column+ or +:!column+.
15
- SYMBOL = "(?<negate>#{Matchers::NEGATE}?)\\s*:(?<name>#{Header::COLUMN_NAME})"
16
- private_constant :SYMBOL
17
-
18
- SYMBOL_RE = Matchers.regexp(SYMBOL)
15
+ SYMBOL_RE =
16
+ Matchers.regexp("(?<negate>#{Matchers::NEGATE}?)\\s*:(?<name>#{Header::COLUMN_NAME})")
19
17
  private_constant :SYMBOL_RE
20
18
 
21
19
  # Column symbol guard expression - e.g., +>:column.present?+ or +:column == 100.0+.
22
- GUARD =
20
+ GUARD_RE = Matchers.regexp(
23
21
  "(?<negate>#{Matchers::NEGATE}?)\\s*" \
24
22
  ":(?<name>#{Header::COLUMN_NAME})\\s*" \
25
23
  "(?<method>!=|=~|!~|<=|>=|>|<|#{Matchers::EQUALS}|\\.)\\s*" \
26
24
  "(?<param>\\S.*)"
27
- private_constant :GUARD
28
-
29
- GUARD_RE = Matchers.regexp(GUARD)
25
+ )
30
26
  private_constant :GUARD_RE
31
27
 
32
28
  # Negated methods
@@ -114,7 +110,7 @@ module CSVDecision
114
110
  method = match['negate'].present? ? '!:' : ':'
115
111
  proc = SYMBOL_PROC[method]
116
112
  symbol = match['name'].to_sym
117
- Matchers::Proc.with(type: :guard, function: proc.curry[symbol].freeze)
113
+ Matchers::Proc.new(type: :guard, symbols: symbol, function: proc.curry[symbol].freeze)
118
114
  end
119
115
  private_class_method :symbol_proc
120
116
 
@@ -124,7 +120,8 @@ module CSVDecision
124
120
 
125
121
  proc, value = guard_proc(match)
126
122
  symbol = match['name'].to_sym
127
- Matchers::Proc.with(type: :guard, function: proc.curry[symbol][value].freeze)
123
+ Matchers::Proc.new(type: :guard, symbols: symbol,
124
+ function: proc.curry[symbol][value].freeze)
128
125
  end
129
126
  private_class_method :symbol_guard
130
127
 
@@ -35,8 +35,8 @@ module CSVDecision
35
35
  return false unless numeric_cell
36
36
 
37
37
  comparator = match['comparator']
38
- Matchers::Proc.with(type: :proc,
39
- function: COMPARATORS[comparator].curry[numeric_cell].freeze)
38
+ Matchers::Proc.new(type: :proc,
39
+ function: COMPARATORS[comparator].curry[numeric_cell].freeze)
40
40
  end
41
41
 
42
42
  # @param (see Matchers::Matcher#matches?)