fat_core 1.7.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dee8f90ed96b24c51a40eaaf816cda967450ed78
4
- data.tar.gz: 83fe257ef4ceba08a7bf11e6ed281a17f452b26f
3
+ metadata.gz: 8c3d2ea26248f15906e7885b3efeaa09ffa10554
4
+ data.tar.gz: 0d14aa12596198d1add2e0ae2922a89411da65fe
5
5
  SHA512:
6
- metadata.gz: 6f7c36cf04a7b5c0b36c8cdd84014f8b31481834dd674869ff1993af8024e2b42fd8cd5e07685173b236f0c16610972f61eb5c996e71c5fa9360f8f36aa3dee9
7
- data.tar.gz: a41b43ff052e3eddf9c46e8047f3ccf424d8070e8afc3bf1b57f5e8fa2fe063057b1800ff8718bff2719429726f9490ce439db07d89b74599e1012b795af520d
6
+ metadata.gz: 9a68397f420d5a775818d7071e12e4bf15aadbe05f77e8fe1a34066bab5c3ab853040be1399d5bd08be587a33bade93cd7bbade821806a18df5f6f5c4508bb12
7
+ data.tar.gz: e1e0c5b69ba7d652c17cf41a788c2d5291c725e9c5fb80cbef1b2edd016146ab67bd4f68b767828bea4d5c5ce9779a47b01bfd6a0299cd3480b9d6bd5ff628c1
data/TODO.org CHANGED
@@ -1,19 +0,0 @@
1
- * Conversion to Spreadsheets
2
- This is a [[https://github.com/westonganger/spreadsheet_architect][gem]] that I can include into the Table model to convert a table into
3
- a spread-sheet, or even a sheet in a multi-sheet spreadsheet file.
4
-
5
- * Formatters
6
- Need to think about ways to define formatters for Table for different output
7
- types, including tty, color-tty, latex, csv, spreadsheet?
8
-
9
- * Add a Group Boundary concept
10
- If I want a table to perform sub-totals at various break points, need to have a
11
- way for a table to record its grouping boundaries. Maybe an array of row
12
- numbers? Automatically injected by the group-by method?
13
-
14
- * DONE Add uniq method and set operations
15
- CLOSED: [2017-03-02 Thu 15:54]
16
- - State "WAIT" from "TODO" [2017-03-02 Thu 15:54]
17
- - State "TODO" from [2017-03-02 Thu 15:54]
18
- For tables, add a method that eliminates any duplicate rows. Perhaps just
19
- apply Array#uniq to the columns?
@@ -109,20 +109,28 @@ class String
109
109
  end
110
110
 
111
111
  def wrap(width = 70, hang = 0)
112
- offset = 0
113
- trip = 1
114
112
  result = ''
115
- while (s = slice(offset, width))
116
- offset += width
117
- if trip == 1
118
- width -= hang
119
- else
120
- s = (' ' * hang) + s
113
+ first_line = true
114
+ first_word_on_line = true
115
+ line_width_so_far = 0
116
+ words = split(' ')
117
+ words.each do |w|
118
+ if !first_line && first_word_on_line
119
+ w = ' ' * hang + w
120
+ end
121
+ unless first_word_on_line
122
+ w = ' ' + w
123
+ end
124
+ result << w
125
+ first_word_on_line = false
126
+ line_width_so_far += 1 + w.length
127
+ if line_width_so_far >= width
128
+ result << "\n"
129
+ line_width_so_far = 0
130
+ first_line = false
131
+ first_word_on_line = true
121
132
  end
122
- result << s + "\n"
123
- trip += 1
124
133
  end
125
- # Remove the final newline before exiting
126
134
  result.strip
127
135
  end
128
136
 
@@ -254,6 +262,10 @@ class String
254
262
  colorize(self, "\001\e[1m\e[35m\002")
255
263
  end
256
264
 
265
+ def console_cyan
266
+ colorize(self, "\001\e[1m\e[36m\002")
267
+ end
268
+
257
269
  def console_def
258
270
  colorize(self, "\001\e[1m\002")
259
271
  end
@@ -1,7 +1,7 @@
1
1
  module FatCore
2
- MAJOR = 1
3
- MINOR = 7
4
- PATCH = 1
2
+ MAJOR = 2
3
+ MINOR = 0
4
+ PATCH = 0
5
5
 
6
6
  VERSION = [MAJOR, MINOR, PATCH].compact.join('.')
7
7
  end
data/lib/fat_core.rb CHANGED
@@ -20,7 +20,3 @@ require 'fat_core/period'
20
20
  require 'fat_core/range'
21
21
  require 'fat_core/string'
22
22
  require 'fat_core/symbol'
23
- require 'fat_core/evaluator'
24
- require 'fat_core/column'
25
- require 'fat_core/table'
26
- require 'fat_core/formatters'
@@ -25,34 +25,36 @@ the last full measure of devotion--that we here highly resolve that th\
25
25
  ese dead shall not have died in vain--that this nation, under God, sha\
26
26
  ll have a new birth of freedom--and that government of the people, by \
27
27
  the people, for the people, shall not perish from the earth."
28
- ##123456789012345678901234567890123456789012345678901234567890123456789|
29
- # @getty = "\
30
- # Four score and seven years ago our fathers brought forth on this conti\
31
- # nent a new nation, conceived in liberty, and dedicated to th\
32
- # e proposition that all men are created equal. Now we are en\
33
- # gaged in a great civil war, testing whether that nation, or \
34
- # any nation, so conceived and so dedicated, can long endure. \
35
- # We are met on a great battle-field of that war. We have come\
36
- # to dedicate a portion of that field, as a final resting pla\
37
- # ce for those who here gave their lives that that nation migh\
38
- # t live. It is altogether fitting and proper that we should d\
39
- # o this. But, in a larger sense, we can not dedicate, we can\
40
- # not consecrate, we can not hallow this ground. The brave me\
41
- # n, living and dead, who struggled here, have consecrated it,\
42
- # far above our poor power to add or detract. The world will \
43
- # little note, nor long remember what we say here, but it can \
44
- # never forget what they did here. It is for us the living, ra\
45
- # ther, to be dedicated here to the unfinished work which they\
46
- # who fought here have thus far so nobly advanced. It is rath\
47
- # er for us to be here dedicated to the great task remaining b\
48
- # efore us--that from these honored dead we take increased dev\
49
- # otion to that cause for which they gave the last full measur\
50
- # e of devotion--that we here highly resolve that these dead s\
51
- # hall not have died in vain--that this nation, under God, sha\
52
- # ll have a new birth of freedom--and that government of the p\
53
- # eople, by the people, for the people, shall not perish from \
54
- # the earth."
55
- ##123456789012345678901234567890123456789012345678901234567890123456789|
28
+
29
+ # 0000000000111111111122222222223333333333444444444455555555556666666666
30
+ # 0123456789012345678901234567890123456789012345678901234567890123456789|
31
+ # Four score and seven years ago our fathers brought forth on
32
+ # this continent a new nation, conceived in liberty, and
33
+ # dedicated to the proposition that all men are created
34
+ # equal. Now we are engaged in a great civil war, testing
35
+ # whether that nation, or any nation, so conceived and
36
+ # so dedicated, can long endure. We are met on a great
37
+ # battle-field of that war. We have come to dedicate a
38
+ # portion of that field, as a final resting place for
39
+ # those who here gave their lives that that nation might
40
+ # live. It is altogether fitting and proper that we should
41
+ # do this. But, in a larger sense, we can not dedicate,
42
+ # we can not consecrate, we can not hallow this ground.
43
+ # The brave men, living and dead, who struggled here,
44
+ # have consecrated it, far above our poor power to add
45
+ # or detract. The world will little note, nor long remember
46
+ # what we say here, but it can never forget what they
47
+ # did here. It is for us the living, rather, to be dedicated
48
+ # here to the unfinished work which they who fought here
49
+ # have thus far so nobly advanced. It is rather for us
50
+ # to be here dedicated to the great task remaining before
51
+ # us--that from these honored dead we take increased devotion
52
+ # to that cause for which they gave the last full measure
53
+ # of devotion--that we here highly resolve that these dead
54
+ # shall not have died in vain--that this nation, under
55
+ # God, shall have a new birth of freedom--and that government
56
+ # of the people, by the people, for the people, shall
57
+ # not perish from the earth.
56
58
  end
57
59
 
58
60
  describe 'class methods' do
@@ -77,20 +79,22 @@ the people, for the people, shall not perish from the earth."
77
79
  end
78
80
 
79
81
  it 'should wrap a long string' do
80
- @getty.wrap.split("\n").each { |l| expect(l.length).to be <= 70 }
82
+ str = @getty.wrap
83
+ str.split("\n").each { |l| expect(l.length).to be <= 70 }
81
84
  end
82
85
 
83
86
  it 'should wrap a long string with a hangining indent' do
84
- @getty.wrap(70, 10).split("\n").each { |l| expect(l.length).to be <= 70 }
85
- @getty.wrap(70, 10).split("\n")[1..-1].each do |l|
87
+ str = @getty.wrap(70, 10)
88
+ str.split("\n").each { |l| expect(l.length).to be <= 70 }
89
+ str.split("\n")[1..-1].each do |l|
86
90
  expect(l).to match(/^ /)
87
91
  end
88
- second_line = ' ' * 10 + 'nent a new nation'
89
- third_line = ' ' * 10 + 'e proposition'
90
- twenty_fourth_line = ' ' * 10 + 'eople, by the people, for the people'
91
- expect(@getty.wrap(70, 10).split("\n")[1]).to match(/^#{second_line}/)
92
- expect(@getty.wrap(70, 10).split("\n")[2]).to match(/^#{third_line}/)
93
- expect(@getty.wrap(70, 10).split("\n")[23]).to match(/^#{twenty_fourth_line}/)
92
+ second_line = ' ' * 10 + 'this continent a new nation'
93
+ third_line = ' ' * 10 + 'dedicated to the proposition'
94
+ twenty_fourth_line = ' ' * 10 + 'shall not have died in vain'
95
+ expect(str.split("\n")[1]).to match(/^#{second_line}/)
96
+ expect(str.split("\n")[2]).to match(/^#{third_line}/)
97
+ expect(str.split("\n")[23]).to match(/^#{twenty_fourth_line}/)
94
98
  end
95
99
 
96
100
  it 'should be able to quote special TeX characters' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fat_core
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Daniel E. Doherty
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-02 00:00:00.000000000 Z
11
+ date: 2017-04-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: simplecov
@@ -204,16 +204,8 @@ files:
204
204
  - lib/fat_core/ChangeLog
205
205
  - lib/fat_core/array.rb
206
206
  - lib/fat_core/boolean.rb
207
- - lib/fat_core/column.rb
208
207
  - lib/fat_core/date.rb
209
208
  - lib/fat_core/enumerable.rb
210
- - lib/fat_core/evaluator.rb
211
- - lib/fat_core/formatters.rb
212
- - lib/fat_core/formatters/aoa_formatter.rb
213
- - lib/fat_core/formatters/aoh_formatter.rb
214
- - lib/fat_core/formatters/formatter.rb
215
- - lib/fat_core/formatters/org_formatter.rb
216
- - lib/fat_core/formatters/text_formatter.rb
217
209
  - lib/fat_core/hash.rb
218
210
  - lib/fat_core/kernel.rb
219
211
  - lib/fat_core/latex_eruby.rb
@@ -223,21 +215,10 @@ files:
223
215
  - lib/fat_core/range.rb
224
216
  - lib/fat_core/string.rb
225
217
  - lib/fat_core/symbol.rb
226
- - lib/fat_core/table.rb
227
218
  - lib/fat_core/version.rb
228
- - spec/example_files/datawatch.org
229
- - spec/example_files/goldberg.org
230
- - spec/example_files/wpcs.csv
231
219
  - spec/lib/array_spec.rb
232
- - spec/lib/column_spec.rb
233
220
  - spec/lib/date_spec.rb
234
221
  - spec/lib/enumerable_spec.rb
235
- - spec/lib/evaluator_spec.rb
236
- - spec/lib/formatters/aoa_formatter_spec.rb
237
- - spec/lib/formatters/aoh_formatter_spec.rb
238
- - spec/lib/formatters/formatter_spec.rb
239
- - spec/lib/formatters/org_formatter_spec.rb
240
- - spec/lib/formatters/text_formatter_spec.rb
241
222
  - spec/lib/hash_spec.rb
242
223
  - spec/lib/kernel_spec.rb
243
224
  - spec/lib/nil_spec.rb
@@ -246,7 +227,6 @@ files:
246
227
  - spec/lib/range_spec.rb
247
228
  - spec/lib/string_spec.rb
248
229
  - spec/lib/symbol_spec.rb
249
- - spec/lib/table_spec.rb
250
230
  - spec/spec_helper.rb
251
231
  homepage: ''
252
232
  licenses:
@@ -273,19 +253,9 @@ signing_key:
273
253
  specification_version: 4
274
254
  summary: fat_core provides some useful core extensions
275
255
  test_files:
276
- - spec/example_files/datawatch.org
277
- - spec/example_files/goldberg.org
278
- - spec/example_files/wpcs.csv
279
256
  - spec/lib/array_spec.rb
280
- - spec/lib/column_spec.rb
281
257
  - spec/lib/date_spec.rb
282
258
  - spec/lib/enumerable_spec.rb
283
- - spec/lib/evaluator_spec.rb
284
- - spec/lib/formatters/aoa_formatter_spec.rb
285
- - spec/lib/formatters/aoh_formatter_spec.rb
286
- - spec/lib/formatters/formatter_spec.rb
287
- - spec/lib/formatters/org_formatter_spec.rb
288
- - spec/lib/formatters/text_formatter_spec.rb
289
259
  - spec/lib/hash_spec.rb
290
260
  - spec/lib/kernel_spec.rb
291
261
  - spec/lib/nil_spec.rb
@@ -294,5 +264,4 @@ test_files:
294
264
  - spec/lib/range_spec.rb
295
265
  - spec/lib/string_spec.rb
296
266
  - spec/lib/symbol_spec.rb
297
- - spec/lib/table_spec.rb
298
267
  - spec/spec_helper.rb
@@ -1,345 +0,0 @@
1
- module FatCore
2
- # Column objects are just a thin wrapper around an Array to allow columns to
3
- # be summed and have other operations performed on them, but compacting out
4
- # nils before proceeding. My original attempt to do this by monkey-patching
5
- # Array turned out badly. This works much nicer.
6
- class Column
7
- attr_reader :header, :raw_header, :type, :items
8
-
9
- TYPES = %w(NilClass Boolean DateTime Numeric String).freeze
10
-
11
- def initialize(header:, items: [])
12
- @raw_header = header
13
- @header =
14
- if @raw_header.is_a?(Symbol)
15
- @raw_header
16
- else
17
- @raw_header.gsub(/[^A-Za-z0-9 ]/, '').as_sym
18
- end
19
- @type = 'NilClass'
20
- raise "Unknown column type '#{type}" unless TYPES.include?(@type.to_s)
21
- @items = []
22
- items.each { |i| self << i }
23
- end
24
-
25
- ##########################################################################
26
- # Attributes
27
- ##########################################################################
28
-
29
- def [](k)
30
- items[k]
31
- end
32
-
33
- def to_a
34
- items
35
- end
36
-
37
- def size
38
- items.size
39
- end
40
-
41
- def empty?
42
- items.empty?
43
- end
44
-
45
- def last_i
46
- size - 1
47
- end
48
-
49
- ##########################################################################
50
- # Aggregates
51
- ##########################################################################
52
-
53
- VALID_AGGREGATES = %s(first last rng
54
- sum count min max avg var dev
55
- any? all? none? one?)
56
-
57
- # Return the first non-nil item in the column. Works with any column type.
58
- def first
59
- items.compact.first
60
- end
61
-
62
- # Return the last non-nil item in the column. Works with any column type.
63
- def last
64
- items.compact.last
65
- end
66
-
67
- # Return a string of the first and last non-nil values. Works with any
68
- # column type.
69
- def rng
70
- "#{first}..#{last}"
71
- end
72
-
73
- # Return the sum of the non-nil items in the column. Works with numeric and
74
- # string columns. For a string column, it will return the concatenation of
75
- # the non-nil items.
76
- def sum
77
- only_with('sum', 'Numeric', 'String')
78
- items.compact.sum
79
- end
80
-
81
- # Return a count of the non-nil items in the column. Works with any column
82
- # type.
83
- def count
84
- items.compact.count
85
- end
86
-
87
- # Return the smallest non-nil item in the column. Works with numeric,
88
- # string, and datetime columns.
89
- def min
90
- only_with('min', 'NilClass', 'Numeric', 'String', 'DateTime')
91
- items.compact.min
92
- end
93
-
94
- # Return the largest non-nil item in the column. Works with numeric,
95
- # string, and datetime columns.
96
- def max
97
- only_with('max', 'NilClass', 'Numeric', 'String', 'DateTime')
98
- items.compact.max
99
- end
100
-
101
- # Return the average value of the non-nil items in the column. Works with
102
- # numeric and datetime columns. For datetime columns, it converts each date
103
- # to its Julian day number, computes the average, and then converts the
104
- # average back to a DateTime.
105
- def avg
106
- only_with('avg', 'DateTime', 'Numeric')
107
- if type == 'DateTime'
108
- avg_jd = items.compact.map(&:jd).sum / items.compact.size.to_d
109
- DateTime.jd(avg_jd)
110
- else
111
- sum / items.compact.size.to_d
112
- end
113
- end
114
-
115
- # Return the variance, the average squared deviation from the mean, of the
116
- # non-nil items in the column. Works with numeric and datetime columns.
117
- # For datetime columns, it converts each date to its Julian day number and
118
- # computes the variance of those numbers.
119
- def var
120
- only_with('var', 'DateTime', 'Numeric')
121
- all_items =
122
- if type == 'DateTime'
123
- items.compact.map(&:jd)
124
- else
125
- items.compact
126
- end
127
- mu = Column.new(header: :mu, items: all_items).avg
128
- sq_dev = 0.0
129
- all_items.compact.each do |itm|
130
- sq_dev += (itm - mu) * (itm - mu)
131
- end
132
- sq_dev / items.compact.size.to_d
133
- end
134
-
135
- # Return the standard deviation, the square root of the variance, of the
136
- # non-nil items in the column. Works with numeric and datetime columns.
137
- # For datetime columns, it converts each date to its Julian day number and
138
- # computes the standard deviation of those numbers.
139
- def dev
140
- only_with('dev', 'DateTime', 'Numeric')
141
- Math.sqrt(var)
142
- end
143
-
144
- # Return true if any of the items in the column are true; otherwise return
145
- # false. Works only with boolean columns.
146
- def any?
147
- only_with('any?', 'Boolean')
148
- items.compact.any?
149
- end
150
-
151
- # Return true if all of the items in the column are true; otherwise return
152
- # false. Works only with boolean columns.
153
- def all?
154
- only_with('all?', 'Boolean')
155
- items.compact.all?
156
- end
157
-
158
- # Return true if none of the items in the column are true; otherwise return
159
- # false. Works only with boolean columns.
160
- def none?
161
- only_with('any?', 'Boolean')
162
- items.compact.none?
163
- end
164
-
165
- # Return true if precisely one of the items in the column is true;
166
- # otherwise return false. Works only with boolean columns.
167
- def one?
168
- only_with('any?', 'Boolean')
169
- items.compact.one?
170
- end
171
-
172
- private
173
-
174
- def only_with(agg, *valid_types)
175
- return self if valid_types.include?(type)
176
- raise "Aggregate '#{agg}' cannot be applied to a #{type} column"
177
- end
178
-
179
- public
180
-
181
- ##########################################################################
182
- # Construction
183
- ##########################################################################
184
-
185
- # Append item to end of the column
186
- def <<(itm)
187
- items << convert_to_type(itm)
188
- end
189
-
190
- # Return a new Column appending the items of other to our items, checking
191
- # for type compatibility.
192
- def +(other)
193
- raise 'Cannot combine columns with different types' unless type == other.type
194
- Column.new(header: header, items: items + other.items)
195
- end
196
-
197
- private
198
-
199
- # Convert val to the type of key, a ruby class constant, such as Date,
200
- # Numeric, etc. If type is NilClass, the type is open, and a non-blank val
201
- # will attempt conversion to one of the allowed types, typing it as a String
202
- # if no other type is recognized. If the val is blank, and the type is nil,
203
- # the column type remains open. If the val is nil or a blank and the type is
204
- # already determined, the val is set to nil, and should be filtered from any
205
- # column computations. If the val is non-blank and the column type
206
- # determined, raise an error if the val cannot be converted to the column
207
- # type. Otherwise, returns the converted val as an object of the correct
208
- # class.
209
- def convert_to_type(val)
210
- case type
211
- when 'NilClass'
212
- if val != false && val.blank?
213
- # Leave the type of the column open. Unfortunately, false counts as
214
- # blank and we don't want it to. It should be classified as a boolean.
215
- new_val = nil
216
- else
217
- # Only non-blank values are allowed to set the type of the column
218
- bool_val = convert_to_boolean(val)
219
- new_val =
220
- if bool_val.nil?
221
- convert_to_date_time(val) ||
222
- convert_to_numeric(val) ||
223
- convert_to_string(val)
224
- else
225
- bool_val
226
- end
227
- @type =
228
- if new_val == true || new_val == false
229
- 'Boolean'
230
- elsif new_val.is_a?(Date) || new_val.is_a?(DateTime)
231
- 'DateTime'
232
- elsif new_val.is_a?(Numeric)
233
- 'Numeric'
234
- elsif new_val.is_a?(String)
235
- 'String'
236
- else
237
- raise "Cannot add #{val} of type #{new_val.class.name} to a column"
238
- end
239
- end
240
- new_val
241
- when 'Boolean'
242
- if val.nil?
243
- nil
244
- else
245
- new_val = convert_to_boolean(val)
246
- if new_val.nil?
247
- raise "Attempt to add '#{val}' to a column already typed as #{type}"
248
- end
249
- new_val
250
- end
251
- when 'DateTime'
252
- if val.nil?
253
- nil
254
- else
255
- new_val = convert_to_date_time(val)
256
- if new_val.nil?
257
- raise "Attempt to add '#{val}' to a column already typed as #{type}"
258
- end
259
- new_val
260
- end
261
- when 'Numeric'
262
- if val.nil?
263
- nil
264
- else
265
- new_val = convert_to_numeric(val)
266
- if new_val.nil?
267
- raise "Attempt to add '#{val}' to a column already typed as #{type}"
268
- end
269
- new_val
270
- end
271
- when 'String'
272
- if val.nil?
273
- nil
274
- else
275
- new_val = convert_to_string(val)
276
- if new_val.nil?
277
- raise "Attempt to add '#{val}' to a column already typed as #{type}"
278
- end
279
- new_val
280
- end
281
- else
282
- raise "Mysteriously, column has unknown type '#{type}'"
283
- end
284
- end
285
-
286
- # Convert the val to a boolean if it looks like one, otherwise return nil.
287
- # Any boolean or a string of t, f, true, false, y, n, yes, or no, regardless
288
- # of case is assumed to be a boolean.
289
- def convert_to_boolean(val)
290
- return val if val.is_a?(TrueClass) || val.is_a?(FalseClass)
291
- val = val.to_s.clean
292
- return nil if val.blank?
293
- if val =~ /\A(false|f|n|no)\z/i
294
- false
295
- elsif val =~ /\A(true|t|y|yes)\z/i
296
- true
297
- end
298
- end
299
-
300
- # Convert the val to a DateTime if it is either a DateTime, a Date, or a
301
- # String that can be parsed as a DateTime, otherwise return nil. It only
302
- # recognizes strings that contain a something like '2016-01-14' or
303
- # '2/12/1985' within them, otherwise DateTime.parse would treat many bare
304
- # numbers as dates, such as '2841381', which it would recognize as a valid
305
- # date, but the user probably does not intend it to be so treated.
306
- def convert_to_date_time(val)
307
- return val if val.is_a?(DateTime)
308
- return val.to_datetime if val.is_a?(Date) && type == 'DateTime'
309
- return val if val.is_a?(Date)
310
- begin
311
- val = val.to_s.clean
312
- return nil if val.blank?
313
- return nil unless val =~ %r{\b\d\d\d\d[-/]\d\d?[-/]\d\d?\b}
314
- val = DateTime.parse(val.to_s.clean)
315
- val = val.to_date if val.seconds_since_midnight.zero?
316
- val
317
- rescue ArgumentError
318
- return nil
319
- end
320
- end
321
-
322
- # Convert the val to a Numeric if is already a Numberic or is a String that
323
- # looks like one. Any Float is promoted to a BigDecimal. Otherwise return
324
- # nil.
325
- def convert_to_numeric(val)
326
- return BigDecimal.new(val, Float::DIG) if val.is_a?(Float)
327
- return val if val.is_a?(Numeric)
328
- # Eliminate any commas, $'s, or _'s.
329
- val = val.to_s.clean.gsub(/[,_$]/, '')
330
- return nil if val.blank?
331
- case val
332
- when /\A(\d+\.\d*)|(\d*\.\d+)\z/
333
- BigDecimal.new(val.to_s.clean)
334
- when /\A[\d]+\z/
335
- val.to_i
336
- when %r{\A(\d+)\s*[:/]\s*(\d+)\z}
337
- Rational($1, $2)
338
- end
339
- end
340
-
341
- def convert_to_string(val)
342
- val.to_s
343
- end
344
- end
345
- end