fat_core 4.7.0 → 4.7.3
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 +4 -4
- data/README.org +377 -0
- data/fat_core.gemspec +3 -3
- data/lib/fat_core/bigdecimal.rb +2 -0
- data/lib/fat_core/date.rb +217 -149
- data/lib/fat_core/enumerable.rb +6 -6
- data/lib/fat_core/hash.rb +9 -10
- data/lib/fat_core/numeric.rb +5 -2
- data/lib/fat_core/patches.rb +2 -0
- data/lib/fat_core/range.rb +6 -1
- data/lib/fat_core/string.rb +25 -28
- data/lib/fat_core/version.rb +1 -1
- data/spec/lib/date_spec.rb +19 -1
- data/spec/lib/string_spec.rb +10 -3
- metadata +9 -9
- data/README.md +0 -165
data/lib/fat_core/enumerable.rb
CHANGED
@@ -6,9 +6,9 @@ module Enumerable
|
|
6
6
|
# # On each iteration, grp is an Array of the next 5 items except the
|
7
7
|
# # last group, which contains only ['z'].
|
8
8
|
# end
|
9
|
-
def groups_of(
|
9
|
+
def groups_of(num)
|
10
10
|
k = -1
|
11
|
-
group_by { k += 1; k.div(
|
11
|
+
group_by { k += 1; k.div(num) }
|
12
12
|
end
|
13
13
|
|
14
14
|
# Yield each item together with two booleans that indicate whether the item is
|
@@ -16,9 +16,9 @@ module Enumerable
|
|
16
16
|
#
|
17
17
|
# ('a'..'z').to_a.each with_flags do |letter, first, last|
|
18
18
|
# if first
|
19
|
-
# # do something special for
|
19
|
+
# # do something special for 'a'
|
20
20
|
# elsif last
|
21
|
-
# # do something special for
|
21
|
+
# # do something special for 'z'
|
22
22
|
# else
|
23
23
|
# # a middling item
|
24
24
|
# end
|
@@ -26,8 +26,8 @@ module Enumerable
|
|
26
26
|
def each_with_flags
|
27
27
|
last_k = size - 1
|
28
28
|
each_with_index do |v, k|
|
29
|
-
first =
|
30
|
-
last = (k == last_k
|
29
|
+
first = k.zero?
|
30
|
+
last = (k == last_k)
|
31
31
|
yield(v, first, last)
|
32
32
|
end
|
33
33
|
end
|
data/lib/fat_core/hash.rb
CHANGED
@@ -46,8 +46,8 @@ module FatCore
|
|
46
46
|
last_k = size - 1
|
47
47
|
k = 0
|
48
48
|
each_pair do |key, val|
|
49
|
-
first =
|
50
|
-
last = (k == last_k
|
49
|
+
first = k.zero?
|
50
|
+
last = (k == last_k)
|
51
51
|
yield(key, val, first, last)
|
52
52
|
k += 1
|
53
53
|
end
|
@@ -64,10 +64,10 @@ module FatCore
|
|
64
64
|
# h.delete_with_value(2) #=> { a: 1, c: 3, e: 1 }
|
65
65
|
# h.delete_with_value([1, 3]) #=> { b: 2, d: 2 }
|
66
66
|
#
|
67
|
-
# @param
|
67
|
+
# @param val [Object, Enumerable<Object>] value to test for
|
68
68
|
# @return [Hash] hash having entries === v or including v deleted
|
69
|
-
def delete_with_value(
|
70
|
-
keys_with_value(
|
69
|
+
def delete_with_value(val)
|
70
|
+
keys_with_value(val).each do |k|
|
71
71
|
delete(k)
|
72
72
|
end
|
73
73
|
self
|
@@ -86,13 +86,11 @@ module FatCore
|
|
86
86
|
# @param val [Object, Enumerable<Object>] value to test for
|
87
87
|
# @return [Array<Object>] the keys with value or values v
|
88
88
|
def keys_with_value(val)
|
89
|
-
|
89
|
+
keys = []
|
90
90
|
each_pair do |k, v|
|
91
|
-
if self[k] == val || (v.respond_to?(:include?) && v.include?(val))
|
92
|
-
result << k
|
93
|
-
end
|
91
|
+
keys << k if self[k] == val || (v.respond_to?(:include?) && v.include?(val))
|
94
92
|
end
|
95
|
-
|
93
|
+
keys
|
96
94
|
end
|
97
95
|
|
98
96
|
# Change each key of this Hash to its value in `key_map`. Keys not appearing in
|
@@ -132,6 +130,7 @@ module FatCore
|
|
132
130
|
unless keys.size == new_keys.size
|
133
131
|
raise ArgumentError, 'replace_keys: new keys size differs from key size'
|
134
132
|
end
|
133
|
+
|
135
134
|
to_a.each_with_index.map { |(_k, v), i| [new_keys[i], v] }.to_h
|
136
135
|
end
|
137
136
|
end
|
data/lib/fat_core/numeric.rb
CHANGED
@@ -133,9 +133,12 @@ module FatCore
|
|
133
133
|
mins, secs = divmod(60)
|
134
134
|
hrs, mins = mins.divmod(60)
|
135
135
|
if frac.round(5) > 0.0
|
136
|
-
'%
|
136
|
+
'%02<hrs>d:%02<mins>d:%02<secs>d.%<frac>d' % { hrs: hrs,
|
137
|
+
mins: mins, secs: secs,
|
138
|
+
frac: frac.round(5) * 100 }
|
137
139
|
else
|
138
|
-
'%
|
140
|
+
'%02<hrs>d:%02<mins>d:%02<secs>d' % { hrs: hrs, mins: mins,
|
141
|
+
secs: secs }
|
139
142
|
end
|
140
143
|
end
|
141
144
|
|
data/lib/fat_core/patches.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# Provide #positive? and #negative? for older versions of Ruby.
|
2
2
|
unless 2.respond_to?(:positive?)
|
3
|
+
# Patch Numeric
|
3
4
|
class Numeric
|
4
5
|
def positive?
|
5
6
|
self > 0
|
@@ -8,6 +9,7 @@ unless 2.respond_to?(:positive?)
|
|
8
9
|
end
|
9
10
|
|
10
11
|
unless 2.respond_to?(:negative?)
|
12
|
+
# Patch Numeric
|
11
13
|
class Numeric
|
12
14
|
def negative?
|
13
15
|
self < 0
|
data/lib/fat_core/range.rb
CHANGED
@@ -62,6 +62,7 @@ module FatCore
|
|
62
62
|
cur_point = min
|
63
63
|
ranges.each do |rr|
|
64
64
|
break if rr.min > max
|
65
|
+
|
65
66
|
if rr.min > cur_point
|
66
67
|
start_point = cur_point
|
67
68
|
end_point = rr.min.pred
|
@@ -96,6 +97,7 @@ module FatCore
|
|
96
97
|
ranges.each do |rr|
|
97
98
|
# Skip ranges outside of self
|
98
99
|
next if rr.max < min || rr.min > max
|
100
|
+
|
99
101
|
# Initialize cur_point to max of first range
|
100
102
|
if cur_point.nil?
|
101
103
|
cur_point = rr.max
|
@@ -125,6 +127,7 @@ module FatCore
|
|
125
127
|
# @return [Range, nil] a Range representing the intersection
|
126
128
|
def intersection(other)
|
127
129
|
return nil unless overlaps?(other)
|
130
|
+
|
128
131
|
([min, other.min].max..[max, other.max].min)
|
129
132
|
end
|
130
133
|
alias & intersection
|
@@ -142,6 +145,7 @@ module FatCore
|
|
142
145
|
# @return [Range, nil] a Range representing the union
|
143
146
|
def union(other)
|
144
147
|
return nil unless overlaps?(other) || contiguous?(other)
|
148
|
+
|
145
149
|
([min, other.min].min..[max, other.max].max)
|
146
150
|
end
|
147
151
|
alias + union
|
@@ -156,6 +160,7 @@ module FatCore
|
|
156
160
|
other.max.respond_to?(:succ) && other.min.respond_to?(:pred)
|
157
161
|
raise 'Range difference requires objects have pred and succ methods'
|
158
162
|
end
|
163
|
+
|
159
164
|
if subset_of?(other)
|
160
165
|
# (4..7) - (0..10)
|
161
166
|
[]
|
@@ -365,7 +370,7 @@ module FatCore
|
|
365
370
|
# @param other [Range] range to compare self with
|
366
371
|
# @return [-1, 0, 1] if self is less, equal, or greater than other
|
367
372
|
def <=>(other)
|
368
|
-
[min, max] <=>
|
373
|
+
[min, max] <=> other.minmax
|
369
374
|
end
|
370
375
|
|
371
376
|
module ClassMethods
|
data/lib/fat_core/string.rb
CHANGED
@@ -55,21 +55,17 @@ module FatCore
|
|
55
55
|
line_width_so_far = 0
|
56
56
|
words = split(' ')
|
57
57
|
words.each do |w|
|
58
|
-
if !first_line && first_word_on_line
|
59
|
-
|
60
|
-
end
|
61
|
-
unless first_word_on_line
|
62
|
-
w = ' ' + w
|
63
|
-
end
|
58
|
+
w = ' ' * hang + w if !first_line && first_word_on_line
|
59
|
+
w = ' ' + w unless first_word_on_line
|
64
60
|
result << w
|
65
61
|
first_word_on_line = false
|
66
62
|
line_width_so_far += 1 + w.length
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
63
|
+
next unless line_width_so_far >= width
|
64
|
+
|
65
|
+
result << "\n"
|
66
|
+
line_width_so_far = 0
|
67
|
+
first_line = false
|
68
|
+
first_word_on_line = true
|
73
69
|
end
|
74
70
|
result.strip
|
75
71
|
end
|
@@ -108,7 +104,9 @@ module FatCore
|
|
108
104
|
#
|
109
105
|
# @return [Date] the translated Date
|
110
106
|
def as_date
|
111
|
-
|
107
|
+
if self =~ %r{(\d\d\d\d)[-/]?(\d\d?)[-/]?(\d\d?)}
|
108
|
+
::Date.new($1.to_i, $2.to_i, $3.to_i)
|
109
|
+
end
|
112
110
|
end
|
113
111
|
|
114
112
|
UPPERS = ('A'..'Z').to_a
|
@@ -121,7 +119,7 @@ module FatCore
|
|
121
119
|
|
122
120
|
# Return true if all the letters in self are upper case
|
123
121
|
def all_upper?
|
124
|
-
tr('^A-Za-z', '').split('').all? {|c| ('A'..'Z').to_a.include? c}
|
122
|
+
tr('^A-Za-z', '').split('').all? { |c| ('A'..'Z').to_a.include? c }
|
125
123
|
end
|
126
124
|
|
127
125
|
public
|
@@ -154,7 +152,7 @@ module FatCore
|
|
154
152
|
words = split(/\s+/)
|
155
153
|
last_k = words.size - 1
|
156
154
|
words.each_with_index do |w, k|
|
157
|
-
first =
|
155
|
+
first = k.zero?
|
158
156
|
last = (k == last_k)
|
159
157
|
if w =~ %r{c/o}i
|
160
158
|
# Care of
|
@@ -273,18 +271,20 @@ module FatCore
|
|
273
271
|
matched_text
|
274
272
|
end
|
275
273
|
|
276
|
-
REGEXP_META_CHARACTERS = "\\$()*+.<>?[]^{|}".chars
|
274
|
+
REGEXP_META_CHARACTERS = "\\$()*+.<>?[]^{|}".chars.freeze
|
277
275
|
|
278
|
-
# Convert a string of the form '/.../Iixm' to a regular
|
279
|
-
# make the regular expression case-insensitive by
|
280
|
-
# modifier syntax to allow '/I' to indicate
|
281
|
-
# surrounding '/',
|
282
|
-
#
|
276
|
+
# Convert a string of the form '/.../Iixm' to a regular
|
277
|
+
# expression. However, make the regular expression case-insensitive by
|
278
|
+
# default and extend the modifier syntax to allow '/I' to indicate
|
279
|
+
# case-sensitive. Without the surrounding '/', quote any Regexp
|
280
|
+
# metacharacters in the string and return a Regexp that matches the string
|
281
|
+
# literally.
|
283
282
|
#
|
284
283
|
# @example
|
285
284
|
# '/Hello/'.as_regexp #=> /Hello/i
|
286
285
|
# '/Hello/I'.as_regexp #=> /Hello/
|
287
286
|
# 'Hello'.as_regexp #=> /Hello/
|
287
|
+
# 'Hello\b'.as_regexp #=> /Hello\\b/
|
288
288
|
#
|
289
289
|
# @return [Regexp]
|
290
290
|
def as_regexp
|
@@ -299,14 +299,10 @@ module FatCore
|
|
299
299
|
flags |= Regexp::MULTILINE if opts.include?('m')
|
300
300
|
end
|
301
301
|
flags = nil if flags.zero?
|
302
|
-
body = Regexp.quote(body) if REGEXP_META_CHARACTERS.include?(body)
|
302
|
+
# body = Regexp.quote(body) if REGEXP_META_CHARACTERS.include?(body)
|
303
303
|
Regexp.new(body, flags)
|
304
304
|
else
|
305
|
-
|
306
|
-
Regexp.new(Regexp.quote(self))
|
307
|
-
else
|
308
|
-
Regexp.new(self)
|
309
|
-
end
|
305
|
+
Regexp.new(Regexp.quote(self))
|
310
306
|
end
|
311
307
|
end
|
312
308
|
|
@@ -327,7 +323,7 @@ module FatCore
|
|
327
323
|
Float(self)
|
328
324
|
true
|
329
325
|
rescue ArgumentError
|
330
|
-
|
326
|
+
false
|
331
327
|
end
|
332
328
|
|
333
329
|
# If the string is a valid number, return a string that adds grouping commas
|
@@ -347,6 +343,7 @@ module FatCore
|
|
347
343
|
def commas(places = nil)
|
348
344
|
numeric_re = /\A([-+])?([\d_]*)((\.)?([\d_]*))?([eE][+-]?[\d_]+)?\z/
|
349
345
|
return self unless clean =~ numeric_re
|
346
|
+
|
350
347
|
sig = $1 || ''
|
351
348
|
whole = $2 ? $2.delete('_') : ''
|
352
349
|
frac = $5 || ''
|
data/lib/fat_core/version.rb
CHANGED
data/spec/lib/date_spec.rb
CHANGED
@@ -219,6 +219,7 @@ describe Date do
|
|
219
219
|
expect(Date.parse_american('2 / 1 / 2011').iso).to eq('2011-02-01')
|
220
220
|
expect(Date.parse_american(' 2 / 1 / 2011 ').iso).to eq('2011-02-01')
|
221
221
|
expect(Date.parse_american(' 2 / 1 / 15 ').iso).to eq('2015-02-01')
|
222
|
+
expect(Date.parse_american(' 2-1-15 ').iso).to eq('2015-02-01')
|
222
223
|
expect {
|
223
224
|
Date.parse_american('xx/1/15')
|
224
225
|
}.to raise_error(ArgumentError)
|
@@ -444,6 +445,7 @@ describe Date do
|
|
444
445
|
it 'should be able to print itself in org form' do
|
445
446
|
expect(Date.today.org).to eq('[2012-07-18 Wed]')
|
446
447
|
expect((Date.today + 1.day).org).to eq('[2012-07-19 Thu]')
|
448
|
+
expect((Date.today + 1.day).org(true)).to eq('<2012-07-19 Thu>')
|
447
449
|
end
|
448
450
|
|
449
451
|
it 'should be able to print itself in eng form' do
|
@@ -610,7 +612,7 @@ describe Date do
|
|
610
612
|
}.to raise_error(ArgumentError)
|
611
613
|
end
|
612
614
|
|
613
|
-
it 'should be able to add a
|
615
|
+
it 'should be able to add a chunk sym to itself' do
|
614
616
|
# Date.today is '2012-07-18'
|
615
617
|
expect(Date.today.add_chunk(:year)).to eq(Date.parse('2013-07-18'))
|
616
618
|
expect(Date.today.add_chunk(:half)).to eq(Date.parse('2013-01-18'))
|
@@ -626,6 +628,22 @@ describe Date do
|
|
626
628
|
}.to raise_error(ArgumentError)
|
627
629
|
end
|
628
630
|
|
631
|
+
it 'should be able to add n chunks sym to itself' do
|
632
|
+
# Date.today is '2012-07-18'
|
633
|
+
expect(Date.today.add_chunk(:year, 5)).to eq(Date.parse('2017-07-18'))
|
634
|
+
expect(Date.today.add_chunk(:half, 5)).to eq(Date.parse('2015-01-18'))
|
635
|
+
expect(Date.today.add_chunk(:quarter, 5)).to eq(Date.parse('2013-10-18'))
|
636
|
+
expect(Date.today.add_chunk(:bimonth, 5)).to eq(Date.parse('2013-05-18'))
|
637
|
+
expect(Date.today.add_chunk(:month, 5)).to eq(Date.parse('2012-12-18'))
|
638
|
+
expect(Date.today.add_chunk(:semimonth, 5)).to eq(Date.parse('2012-10-03'))
|
639
|
+
expect(Date.today.add_chunk(:biweek, 5)).to eq(Date.parse('2012-09-26'))
|
640
|
+
expect(Date.today.add_chunk(:week, 5)).to eq(Date.parse('2012-08-22'))
|
641
|
+
expect(Date.today.add_chunk(:day, 5)).to eq(Date.parse('2012-07-23'))
|
642
|
+
expect {
|
643
|
+
Date.today.add_chunk(:hour)
|
644
|
+
}.to raise_error(ArgumentError)
|
645
|
+
end
|
646
|
+
|
629
647
|
it 'should know the end of chunks' do
|
630
648
|
expect(Date.parse('2013-07-04').end_of_chunk(:year))
|
631
649
|
.to eq Date.parse('2013-12-31')
|
data/spec/lib/string_spec.rb
CHANGED
@@ -150,30 +150,37 @@ the people, for the people, shall not perish from the earth."
|
|
150
150
|
end
|
151
151
|
|
152
152
|
it 'should be able to convert a string to a regular expression' do
|
153
|
+
# Ignores case by default
|
153
154
|
re = "/hello((\s+)(world))?/".as_regexp
|
154
155
|
expect(re.class).to eq Regexp
|
155
156
|
expect(re.casefold?).to be true
|
156
157
|
expect(re.multiline?).to be false
|
157
158
|
expect(re.match?('Hello WorlD')).to be true
|
158
159
|
|
160
|
+
# Countermand ignore case with /.../I modifier
|
159
161
|
re = "/hello((\s+)(world))?/Im".as_regexp
|
160
162
|
expect(re.class).to eq Regexp
|
161
163
|
expect(re.casefold?).to be false
|
162
164
|
expect(re.multiline?).to be true
|
163
165
|
expect(re.match?('Hello WorlD')).to be false
|
164
166
|
|
165
|
-
# Works without /../ but
|
166
|
-
|
167
|
+
# Works without /../ but takes meta-characters literally
|
168
|
+
str = "hello((\s+)(world))?"
|
169
|
+
re = str.as_regexp
|
167
170
|
expect(re.class).to eq Regexp
|
168
171
|
expect(re.casefold?).to be false
|
169
172
|
expect(re.multiline?).to be false
|
170
|
-
expect(re.match?('hello world')).to be
|
173
|
+
expect(re.match?('hello world')).to be false
|
174
|
+
expect(re.match?(str)).to be true
|
175
|
+
expect('Hello\b'.as_regexp).to eq %r{Hello\\b}
|
176
|
+
expect('Hello'.as_regexp).to eq %r{Hello}
|
171
177
|
end
|
172
178
|
|
173
179
|
it 'should be able to convert metacharacters into Regexp' do
|
174
180
|
"\\$()*+.<>?[]^{|}".chars.each do |c|
|
175
181
|
re = c.as_regexp
|
176
182
|
expect(re.class).to eq Regexp
|
183
|
+
expect(re.match?(c)).to be true
|
177
184
|
end
|
178
185
|
end
|
179
186
|
|
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: 4.7.
|
4
|
+
version: 4.7.3
|
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:
|
11
|
+
date: 2020-01-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: simplecov
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: bundler
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - "
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '
|
33
|
+
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - "
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '
|
40
|
+
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,7 +164,7 @@ dependencies:
|
|
164
164
|
- - ">="
|
165
165
|
- !ruby/object:Gem::Version
|
166
166
|
version: '0'
|
167
|
-
description:
|
167
|
+
description: Useful extensions to Date, String, Range and other classes
|
168
168
|
email:
|
169
169
|
- ded@ddoherty.net
|
170
170
|
executables:
|
@@ -179,7 +179,7 @@ files:
|
|
179
179
|
- ".yardopts"
|
180
180
|
- Gemfile
|
181
181
|
- LICENSE.txt
|
182
|
-
- README.
|
182
|
+
- README.org
|
183
183
|
- Rakefile
|
184
184
|
- TODO.org
|
185
185
|
- bin/console
|
@@ -213,7 +213,7 @@ files:
|
|
213
213
|
- spec/lib/string_spec.rb
|
214
214
|
- spec/lib/symbol_spec.rb
|
215
215
|
- spec/spec_helper.rb
|
216
|
-
homepage:
|
216
|
+
homepage: https://github.com/ddoherty03/fat_core.git
|
217
217
|
licenses:
|
218
218
|
- MIT
|
219
219
|
metadata:
|
data/README.md
DELETED
@@ -1,165 +0,0 @@
|
|
1
|
-
[](https://travis-ci.org/ddoherty03/fat_core)
|
2
|
-
|
3
|
-
# FatCore
|
4
|
-
|
5
|
-
fat-core is a simple gem to collect core extensions and a few new classes that
|
6
|
-
I find useful in multiple projects. The emphasis is on extending the Date
|
7
|
-
class to make it more useful in financial applications.
|
8
|
-
|
9
|
-
## Usage
|
10
|
-
|
11
|
-
You can extend classes individually by requiring the corresponding file:
|
12
|
-
|
13
|
-
```
|
14
|
-
require 'fat_core/array'
|
15
|
-
require 'fat_core/bigdecimal'
|
16
|
-
require 'fat_core/date'
|
17
|
-
require 'fat_core/enumerable'
|
18
|
-
require 'fat_core/hash'
|
19
|
-
require 'fat_core/kernel'
|
20
|
-
require 'fat_core/numeric'
|
21
|
-
require 'fat_core/range'
|
22
|
-
require 'fat_core/string'
|
23
|
-
require 'fat_core/symbol'
|
24
|
-
```
|
25
|
-
|
26
|
-
Or, you can require them all:
|
27
|
-
|
28
|
-
```
|
29
|
-
require 'fat_core/all'
|
30
|
-
```
|
31
|
-
|
32
|
-
Many of these have little that is of general interest, but there are a few
|
33
|
-
goodies.
|
34
|
-
|
35
|
-
### Date
|
36
|
-
|
37
|
-
For example, the `Date` class adds two methods for determining whether a given
|
38
|
-
date is a US federal holiday as defined by federal law, including such things as
|
39
|
-
federal holidays established by executive decree:
|
40
|
-
|
41
|
-
```
|
42
|
-
require 'fat_core/date'
|
43
|
-
Date.parse('2014-05-18').fed_holiday? => true # It's a weekend
|
44
|
-
Date.parse('2014-01-01').fed_holiday? => true # It's New Years
|
45
|
-
```
|
46
|
-
|
47
|
-
Likewise, days on which the NYSE is closed can be gotten with:
|
48
|
-
|
49
|
-
```
|
50
|
-
Date.parse('2014-04-18').nyse_holiday? => true # It's Good Friday
|
51
|
-
```
|
52
|
-
|
53
|
-
Conversely, `Date#fed_workday?` and `Date#nyse_workday?` return true if the
|
54
|
-
federal government and the NYSE respectively are open for business on those
|
55
|
-
days.
|
56
|
-
|
57
|
-
In addition, the Date class, as extended by FatCore, adds `#next_<chunk>`
|
58
|
-
methods for calendar periods in addition to those provided by the core Date
|
59
|
-
class: `#next_half`, `#next_quarter`, `#next_bimonth`, and `#next_semimonth`,
|
60
|
-
`#next_biweek`. There are also `#prior_<chunk>` variants of these, as well as
|
61
|
-
methods for finding the end and beginning of all these periods (e.g.,
|
62
|
-
`#beginning_of_bimonth`) and for querying whether a Date is at the beginning or
|
63
|
-
end of these periods (e.g., `#beginning_of_bimonth?`, `#end_of_bimonth?`, etc.).
|
64
|
-
|
65
|
-
FatCore also provides convenience formatting methods, such as `Date#iso` for
|
66
|
-
quickly converting a Date to a string of the form 'YYYY-MM-DD', `Date#org` for
|
67
|
-
formatting a Date as an Emacs org-mode timestamp, and several others.
|
68
|
-
|
69
|
-
Finally, it provides a `#parse_spec` method for parsing a string, typically
|
70
|
-
provided by a user, allowing all the period chunks to be conveniently and
|
71
|
-
tersely specified by a user. For example, the string '2Q' will be parsed as the
|
72
|
-
second calendar quarter of the current year, while '2014-3Q' will be parsed as
|
73
|
-
the third quarter of the year 2014.
|
74
|
-
|
75
|
-
### Range
|
76
|
-
|
77
|
-
You can also extend the Range class with several useful methods that emphasize
|
78
|
-
coverage of one range by one or more others (`#spanned_by?` and `#gaps`),
|
79
|
-
contiguity of Ranges to one another (`#contiguous?`, `#left_contiguous`, and
|
80
|
-
`#right_contiguous`, `#join`), and the testing of overlaps between ranges
|
81
|
-
(`#overlaps?`, `#overlaps_among?`). These are put to good use in the
|
82
|
-
'fat_period' (https://github.com/ddoherty03/fat_period) gem, which combines
|
83
|
-
fat_core's extended Range class with its extended Date class to make a useful
|
84
|
-
Period class for date ranges, and you may find fat_core's extended Range class
|
85
|
-
likewise useful.
|
86
|
-
|
87
|
-
For example, you can use the `#gaps` method to find the gaps left in the
|
88
|
-
coverage on one Range by an Array of other Ranges:
|
89
|
-
|
90
|
-
```
|
91
|
-
require 'fat_core/range'
|
92
|
-
(0..12).gaps([(0..2), (5..7), (10..12)]) => [(3..4), (8..9)]
|
93
|
-
```
|
94
|
-
|
95
|
-
### Enumerable
|
96
|
-
|
97
|
-
FatCore::Enumerable extends Enumerable with the `#each_with_flags` method that
|
98
|
-
yields the elements of the Enumerable but also yields two booleans, `first` and
|
99
|
-
`last` that are set to true on respectively, the first and last element of the
|
100
|
-
Enumerable. This makes it easy to treat these two cases specially without
|
101
|
-
testing the index as in `#each_with_index`.
|
102
|
-
|
103
|
-
### Hash
|
104
|
-
|
105
|
-
FatCore::Hash extends the Hash class with some useful methods for element
|
106
|
-
deletion (`#delete_with_value`) and for manipulating the keys
|
107
|
-
(`#keys_with_value`, `#remap_keys` and `#replace_keys`) of a Hash. It also
|
108
|
-
provides `#each_pair_with_flags` as an analog to Enumerable's
|
109
|
-
`#each_with_flags`.
|
110
|
-
|
111
|
-
### TeX Quoting
|
112
|
-
|
113
|
-
Several of the extension, most notably 'fat_core/string', provides a
|
114
|
-
`#tex_quote` method for quoting the string version of an object so as to allow
|
115
|
-
its inclusion in a TeX document and quote characters such as '$' or '%' that
|
116
|
-
have a special meaning for TeX.
|
117
|
-
|
118
|
-
### String
|
119
|
-
|
120
|
-
FatCore::String has methods for performing matching of one string with another
|
121
|
-
(`#matches_with`, `#fuzzy_match`), for converting a string to title-case as
|
122
|
-
might by used in the title of a book (`#entitle`), for converting a String into
|
123
|
-
a useable Symbol (`#as_sym`) and vice-versa (`#as_string` also
|
124
|
-
`Symbol#as_string`), for wrapping with an optional hanging indent (`#wrap`),
|
125
|
-
cleaning up errant spaces (`#clean`), and computing the Damerau-Levenshtein
|
126
|
-
distance between strings (`#distance`). And several others.
|
127
|
-
|
128
|
-
### Numbers
|
129
|
-
|
130
|
-
FatCore::Numeric has methods for inserting grouping commas into a number
|
131
|
-
(`#commas` and `#group`), for converting seconds to HH:MM:SS.dd format
|
132
|
-
(`#secs_to_hms`), for testing for integrality (`#whole?` and `#int_if_whole`), and
|
133
|
-
testing for sign (`#signum`).
|
134
|
-
|
135
|
-
## Installation
|
136
|
-
|
137
|
-
Add this line to your application's Gemfile:
|
138
|
-
|
139
|
-
```
|
140
|
-
gem 'fat_core', :git => 'https://github.com/ddoherty03/fat_core.git'
|
141
|
-
```
|
142
|
-
|
143
|
-
And then execute:
|
144
|
-
|
145
|
-
```
|
146
|
-
$ bundle
|
147
|
-
```
|
148
|
-
|
149
|
-
Or install it yourself as:
|
150
|
-
|
151
|
-
```
|
152
|
-
$ gem install fat_core
|
153
|
-
```
|
154
|
-
|
155
|
-
## Usage
|
156
|
-
|
157
|
-
TODO: Write usage instructions here
|
158
|
-
|
159
|
-
## Contributing
|
160
|
-
|
161
|
-
1. Fork it ( http://github.com/<my-github-username>/fat_core/fork )
|
162
|
-
2. Create your feature branch (`git checkout -b my-new-feature`)
|
163
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
164
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
165
|
-
5. Create new Pull Request
|