fat_core 1.7.1 → 2.0.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: 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