active_object 2.5.2 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile +2 -2
- data/LICENSE.txt +2 -2
- data/README.md +127 -54
- data/active_object.gemspec +5 -4
- data/bin/rake +6 -6
- data/lib/active_object.rb +25 -1
- data/lib/active_object/array.rb +91 -80
- data/lib/active_object/configuration.rb +21 -0
- data/lib/active_object/date.rb +31 -98
- data/lib/active_object/enumerable.rb +20 -26
- data/lib/active_object/hash.rb +73 -94
- data/lib/active_object/integer.rb +8 -17
- data/lib/active_object/numeric.rb +125 -129
- data/lib/active_object/object.rb +19 -25
- data/lib/active_object/range.rb +12 -14
- data/lib/active_object/string.rb +154 -224
- data/lib/active_object/time.rb +54 -146
- data/lib/active_object/version.rb +2 -2
- data/lib/generators/active_object/install_generator.rb +12 -0
- data/lib/generators/active_object/templates/install.rb +12 -0
- metadata +21 -4
data/active_object.gemspec
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
# coding: utf-8
|
2
|
-
lib = File.expand_path(
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
4
|
+
require "active_object/version"
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "active_object"
|
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
|
|
11
11
|
|
12
12
|
spec.summary = %q{Gem for commonly used ruby object helpers.}
|
13
13
|
spec.description = %q{Class extensions of commonly used ruby object helpers.}
|
14
|
-
spec.homepage = "
|
14
|
+
spec.homepage = "http://drexed.github.io/active_object"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
17
17
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
@@ -23,4 +23,5 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "coveralls"
|
24
24
|
spec.add_development_dependency "rake"
|
25
25
|
spec.add_development_dependency "rspec", "~> 3.4.0"
|
26
|
-
|
26
|
+
spec.add_development_dependency "generator_spec"
|
27
|
+
end
|
data/bin/rake
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
#
|
3
3
|
# This file was generated by Bundler.
|
4
4
|
#
|
5
|
-
# The application
|
5
|
+
# The application "rake" is installed as part of a gem, and
|
6
6
|
# this file is here to facilitate running it.
|
7
7
|
#
|
8
8
|
|
9
|
-
require
|
10
|
-
ENV[
|
9
|
+
require "pathname"
|
10
|
+
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile",
|
11
11
|
Pathname.new(__FILE__).realpath)
|
12
12
|
|
13
|
-
require
|
14
|
-
require
|
13
|
+
require "rubygems"
|
14
|
+
require "bundler/setup"
|
15
15
|
|
16
|
-
load Gem.bin_path(
|
16
|
+
load Gem.bin_path("rake", "rake")
|
data/lib/active_object.rb
CHANGED
@@ -1,4 +1,26 @@
|
|
1
1
|
require "active_object/version"
|
2
|
+
require "active_object/configuration"
|
3
|
+
|
4
|
+
module ActiveObject
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_accessor :configuration
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.configuration
|
11
|
+
@configuration ||= Configuration.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.configuration=(config)
|
15
|
+
@configuration = config
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.configure
|
19
|
+
yield(configuration)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
2
24
|
require "active_object/array"
|
3
25
|
require "active_object/date"
|
4
26
|
require "active_object/enumerable"
|
@@ -8,4 +30,6 @@ require "active_object/numeric"
|
|
8
30
|
require "active_object/object"
|
9
31
|
require "active_object/range"
|
10
32
|
require "active_object/string"
|
11
|
-
require "active_object/time"
|
33
|
+
require "active_object/time"
|
34
|
+
|
35
|
+
require "generators/active_object/install_generator"
|
data/lib/active_object/array.rb
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
module ActiveObject::Array
|
2
2
|
|
3
3
|
def after(value)
|
4
4
|
return(nil) unless include?(value)
|
@@ -34,6 +34,16 @@ class Array
|
|
34
34
|
return(result)
|
35
35
|
end
|
36
36
|
|
37
|
+
def dig(key, *rest)
|
38
|
+
if value = (self[key] rescue nil)
|
39
|
+
if rest.empty?
|
40
|
+
value
|
41
|
+
elsif value.respond_to?(:dig)
|
42
|
+
value.dig(*rest)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
37
47
|
def duplicates(minimum=2)
|
38
48
|
hash = Hash.new(0)
|
39
49
|
|
@@ -41,64 +51,69 @@ class Array
|
|
41
51
|
hash.delete_if { |k, v| v < minimum }.keys
|
42
52
|
end
|
43
53
|
|
44
|
-
|
45
|
-
|
46
|
-
self[position, length] || []
|
47
|
-
end
|
54
|
+
def from(position)
|
55
|
+
self[position, length] || []
|
48
56
|
end
|
49
57
|
|
50
58
|
def groups(number)
|
51
59
|
return([]) if number <= 0
|
52
60
|
|
53
|
-
n, r
|
61
|
+
n, r = length.divmod(number)
|
54
62
|
collection = (0..(n - 1)).collect { |i| self[(i * number), number] }
|
55
63
|
r > 0 ? collection << self[-r, r] : collection
|
56
64
|
end
|
57
65
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
modulo = collection_length % number
|
63
|
-
|
64
|
-
collection = []
|
65
|
-
start = 0
|
66
|
-
number.times do |i|
|
67
|
-
grouping = division + (modulo > 0 && modulo > i ? 1 : 0)
|
68
|
-
collection << last_group = slice(start, grouping)
|
69
|
-
last_group << fill_with if fill_with != false && modulo > 0 && grouping == division
|
70
|
-
start += grouping
|
71
|
-
end
|
66
|
+
def in_groups(number, fill_with=nil)
|
67
|
+
collection_length = length
|
68
|
+
division = collection_length.div(number)
|
69
|
+
modulo = collection_length % number
|
72
70
|
|
73
|
-
|
71
|
+
collection = []
|
72
|
+
start = 0
|
73
|
+
number.times do |i|
|
74
|
+
grouping = division + (modulo > 0 && modulo > i ? 1 : 0)
|
75
|
+
collection << last_group = slice(start, grouping)
|
76
|
+
last_group << fill_with if fill_with != false && modulo > 0 && grouping == division
|
77
|
+
start += grouping
|
74
78
|
end
|
79
|
+
|
80
|
+
block_given? ? collection.each { |g| yield(g) } : collection
|
75
81
|
end
|
76
82
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
end
|
83
|
+
def in_groups_of(number, fill_with=nil)
|
84
|
+
if number.to_i <= 0
|
85
|
+
raise ArgumentError,
|
86
|
+
"Group length must be a positive integer, was #{number.inspect}"
|
87
|
+
end
|
83
88
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
89
|
+
if fill_with == false
|
90
|
+
collection = self
|
91
|
+
else
|
92
|
+
padding = (number - length % number) % number
|
93
|
+
collection = dup.concat(Array.new(padding, fill_with))
|
94
|
+
end
|
90
95
|
|
91
|
-
|
96
|
+
block_given? ? collection.each_slice(number) { |slice| yield(slice) } : collection.each_slice(number).to_a
|
97
|
+
end
|
98
|
+
|
99
|
+
def percentile(percentage)
|
100
|
+
size = self.size
|
101
|
+
|
102
|
+
if size > 1
|
103
|
+
index = size * percentage / 100.0
|
104
|
+
self.sort[index]
|
105
|
+
else
|
106
|
+
self.first
|
92
107
|
end
|
93
108
|
end
|
94
109
|
|
95
110
|
def probability
|
96
|
-
hash
|
111
|
+
hash = Hash.new(0.0)
|
97
112
|
differ = 0.0
|
98
113
|
|
99
114
|
each do |e|
|
100
115
|
hash[e] += 1.0
|
101
|
-
differ
|
116
|
+
differ += 1.0
|
102
117
|
end
|
103
118
|
|
104
119
|
hash.keys.each { |e| hash[e] /= differ }
|
@@ -113,26 +128,24 @@ class Array
|
|
113
128
|
delete_at(Random.rand(length - 1))
|
114
129
|
end
|
115
130
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
yield(element) ? results << [] : results.last << element
|
121
|
-
results
|
122
|
-
end
|
123
|
-
else
|
124
|
-
results, arr = [[]], dup
|
125
|
-
until arr.empty?
|
126
|
-
if (idx = arr.index(number))
|
127
|
-
results.last.concat(arr.shift(idx))
|
128
|
-
arr.shift
|
129
|
-
results << []
|
130
|
-
else
|
131
|
-
results.last.concat(arr.shift(arr.length))
|
132
|
-
end
|
133
|
-
end
|
131
|
+
def split(number=nil)
|
132
|
+
if block_given?
|
133
|
+
inject([[]]) do |results, element|
|
134
|
+
yield(element) ? results << [] : results.last << element
|
134
135
|
results
|
135
136
|
end
|
137
|
+
else
|
138
|
+
results, arr = [[]], dup
|
139
|
+
until arr.empty?
|
140
|
+
if (idx = arr.index(number))
|
141
|
+
results.last.concat(arr.shift(idx))
|
142
|
+
arr.shift
|
143
|
+
results << []
|
144
|
+
else
|
145
|
+
results.last.concat(arr.shift(arr.length))
|
146
|
+
end
|
147
|
+
end
|
148
|
+
results
|
136
149
|
end
|
137
150
|
end
|
138
151
|
|
@@ -144,34 +157,32 @@ class Array
|
|
144
157
|
replace(strip)
|
145
158
|
end
|
146
159
|
|
147
|
-
|
148
|
-
|
149
|
-
position >= 0 ? first(position + 1) : self[0..position]
|
150
|
-
end
|
160
|
+
def to(position)
|
161
|
+
position >= 0 ? first(position + 1) : self[0..position]
|
151
162
|
end
|
152
163
|
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
|
173
|
-
end
|
164
|
+
def to_sentence(options={})
|
165
|
+
options.assert_valid_keys(:words_connector, :two_words_connector, :last_word_connector)
|
166
|
+
|
167
|
+
default_connectors = {
|
168
|
+
words_connector: ", ",
|
169
|
+
two_words_connector: " and ",
|
170
|
+
last_word_connector: ", and "
|
171
|
+
}
|
172
|
+
options = default_connectors.merge!(options)
|
173
|
+
|
174
|
+
case length
|
175
|
+
when 0
|
176
|
+
""
|
177
|
+
when 1
|
178
|
+
self[0].to_s.dup
|
179
|
+
when 2
|
180
|
+
"#{self[0]}#{options[:two_words_connector]}#{self[1]}"
|
181
|
+
else
|
182
|
+
"#{self[0...-1].join(options[:words_connector])}#{options[:last_word_connector]}#{self[-1]}"
|
174
183
|
end
|
175
184
|
end
|
176
185
|
|
177
|
-
end
|
186
|
+
end
|
187
|
+
|
188
|
+
Array.send(:include, ActiveObject::Array) if ActiveObject.configuration.autoload_array
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class ActiveObject::Configuration
|
2
|
+
|
3
|
+
attr_accessor :autoload_array, :autoload_date, :autoload_enumerable,
|
4
|
+
:autoload_hash, :autoload_integer, :autoload_numeric,
|
5
|
+
:autoload_object, :autoload_range, :autoload_string,
|
6
|
+
:autoload_time
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
@autoload_array = true
|
10
|
+
@autoload_date = true
|
11
|
+
@autoload_enumerable = true
|
12
|
+
@autoload_hash = true
|
13
|
+
@autoload_integer = true
|
14
|
+
@autoload_numeric = true
|
15
|
+
@autoload_object = true
|
16
|
+
@autoload_range = true
|
17
|
+
@autoload_string = true
|
18
|
+
@autoload_time = true
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
data/lib/active_object/date.rb
CHANGED
@@ -1,111 +1,44 @@
|
|
1
|
-
|
1
|
+
module ActiveObject::Date
|
2
|
+
|
3
|
+
STRING_UNITS = {
|
4
|
+
d: "d", day: "d", day_padded: "d", dd: "-d", Day: "-d", day_unpadded: "-d",
|
5
|
+
ddd: "_d", DAY: "_d", day_blank: "_d", dddd: "j", day_of_the_year: "j",
|
6
|
+
m: "m", month: "m", month_padded: "m", mm: "-m", Month: "-m",
|
7
|
+
month_unpadded: "-m", mmm: "_m", MONTH: "_m", month_blank: "_m", mmmm: "B",
|
8
|
+
month_name: "B", mmmmm: "b", month_name_abbr: "b", w: "u", weekday: "u",
|
9
|
+
ww: "w", weekday_offset: "w", www: "A", weekday_name: "A", wwww: "a",
|
10
|
+
weekday_name_abbr: "a", wwwww: "W", week: "W", wwwwww: "U", week_offset: "U",
|
11
|
+
yy: "y", yr: "y", yyyy: "Y", year: "Y"
|
12
|
+
}
|
13
|
+
KEY_UNITS = {
|
14
|
+
month: "%m", month_padded: "%m", month_unpadded: "%-m", month_blank: "%_m",
|
15
|
+
month_name: "%B", month_name_abbr: "%b", month_year: "%m %Y",
|
16
|
+
month_padded_year: "%m %Y", month_unpadded_year: "%-m %Y",
|
17
|
+
month_blank_year: "%_m %Y", month_name_year: "%B %Y",
|
18
|
+
month_name_abbr_year: "%b %Y", weekday: "%d", weekday_padded: "%d",
|
19
|
+
weekday_unpadded: "%-d", weekday_blank: "%_d", weekday_name: "%A",
|
20
|
+
weekday_name_abbr: "%a", yr: "%y", year_abbr: "%y", year: "%Y",
|
21
|
+
date: "%B %-d, %Y", date_abbr:"%b %-d, %Y", date_iso: "%Y-%m-%d",
|
22
|
+
day: "%B %-d", day_abbr: "%b %-d", day_iso: "%m-%d"
|
23
|
+
}
|
2
24
|
|
3
25
|
def format(string)
|
4
26
|
delimiters = string.scan(/\W+/)
|
5
27
|
formatters = string.scan(/[a-z0-9_]+/i)
|
6
28
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
'day_padded' => 'd',
|
11
|
-
'dd' => '-d',
|
12
|
-
'Day' => '-d',
|
13
|
-
'day_unpadded' => '-d',
|
14
|
-
'ddd' => '_d',
|
15
|
-
'DAY' => '_d',
|
16
|
-
'day_blank' => '_d',
|
17
|
-
'dddd' => 'j',
|
18
|
-
'day_of_the_year' => 'j',
|
19
|
-
'm' => 'm',
|
20
|
-
'month' => 'm',
|
21
|
-
'month_padded' => 'm',
|
22
|
-
'mm' => '-m',
|
23
|
-
'Month' => '-m',
|
24
|
-
'month_unpadded' => '-m',
|
25
|
-
'mmm' => '_m',
|
26
|
-
'MONTH' => '_m',
|
27
|
-
'month_blank' => '_m',
|
28
|
-
'mmmm' => 'B',
|
29
|
-
'month_name' => 'B',
|
30
|
-
'mmmmm' => 'b',
|
31
|
-
'month_name_abbr' => 'b',
|
32
|
-
'w' => 'u',
|
33
|
-
'weekday' => 'u',
|
34
|
-
'ww' => 'w',
|
35
|
-
'weekday_offset' => 'w',
|
36
|
-
'www' => 'A',
|
37
|
-
'weekday_name' => 'A',
|
38
|
-
'wwww' => 'a',
|
39
|
-
'weekday_name_abbr' => 'a',
|
40
|
-
'wwwww' => 'W',
|
41
|
-
'week' => 'W',
|
42
|
-
'wwwwww' => 'U',
|
43
|
-
'week_offset' => 'U',
|
44
|
-
'yy' => 'y',
|
45
|
-
'yr' => 'y',
|
46
|
-
'yyyy' => 'Y',
|
47
|
-
'year' => 'Y',
|
48
|
-
'ampm' => 'P',
|
49
|
-
'meridian' => 'P',
|
50
|
-
'AMPM' => 'p',
|
51
|
-
'MERIDIAN' => 'p'
|
52
|
-
}.freeze
|
29
|
+
string = formatters.map do |unit|
|
30
|
+
"%#{STRING_UNITS.fetch(unit.to_sym)}#{delimiters.shift || ''}"
|
31
|
+
end
|
53
32
|
|
54
|
-
strftime(
|
33
|
+
strftime(string.join)
|
55
34
|
end
|
56
35
|
|
57
36
|
def to_format(key=:datetime_iso)
|
58
|
-
|
59
|
-
month: '%m',
|
60
|
-
month_padded: '%m',
|
61
|
-
month_unpadded: '%-m',
|
62
|
-
month_blank: '%_m',
|
63
|
-
month_name: '%B',
|
64
|
-
month_name_abbr: '%b',
|
65
|
-
month_year: '%m %Y',
|
66
|
-
month_padded_year: '%m %Y',
|
67
|
-
month_unpadded_year: '%-m %Y',
|
68
|
-
month_blank_year: '%_m %Y',
|
69
|
-
month_name_year: '%B %Y',
|
70
|
-
month_name_abbr_year: '%b %Y',
|
71
|
-
weekday: '%d',
|
72
|
-
weekday_padded: '%d',
|
73
|
-
weekday_unpadded: '%-d',
|
74
|
-
weekday_blank: '%_d',
|
75
|
-
weekday_name: '%A',
|
76
|
-
weekday_name_abbr: '%a',
|
77
|
-
yr: '%y',
|
78
|
-
year_abbr: '%y',
|
79
|
-
year: '%Y',
|
80
|
-
date: '%B %-d, %Y',
|
81
|
-
date_abbr: '%b %-d, %Y',
|
82
|
-
date_iso: '%Y-%m-%d',
|
83
|
-
datetime: '%B %-d, %Y %H:%M',
|
84
|
-
datetime_abbr: '%b %-d, %Y %H:%M',
|
85
|
-
datetime_iso: '%Y-%m-%d %H:%M',
|
86
|
-
datetime_imperical: '%B %-d, %Y %I:%M %P',
|
87
|
-
datetime_imperical_abbr: '%b %-d, %Y %I:%M %P',
|
88
|
-
datetime_imperical_iso: '%Y-%m-%d %I:%M %P',
|
89
|
-
datetime_tzn: '%B %-d, %Y %H:%M %Z',
|
90
|
-
datetime_abbr_tzn: '%b %-d, %Y %H:%M %Z',
|
91
|
-
datetime_iso_tzn: '%Y-%m-%d %H:%M %z',
|
92
|
-
datetime_imperical_tzn: '%B %-d, %Y %I:%M %P %Z',
|
93
|
-
datetime_imperical_abbr_tzn: '%b %-d, %Y %I:%M %P %Z',
|
94
|
-
datetime_imperical_iso_tzn: '%Y-%m-%d %I:%M %P %z',
|
95
|
-
day: '%B %-d',
|
96
|
-
day_abbr: '%b %-d',
|
97
|
-
day_iso: '%m-%d',
|
98
|
-
daytime: '%B %-d %H:%M',
|
99
|
-
daytime_abbr: '%b %-d %H:%M',
|
100
|
-
daytime_iso: '%m-%d %H:%M',
|
101
|
-
daytime_imperical: '%B %-d %I:%M %P',
|
102
|
-
daytime_imperical_abbr: '%b %-d %I:%M %P',
|
103
|
-
daytime_imperical_iso: '%m-%d %I:%M %P'
|
104
|
-
}.freeze
|
105
|
-
|
106
|
-
strftime(format_units.fetch(key.to_sym))
|
37
|
+
strftime(KEY_UNITS.fetch(key.to_sym))
|
107
38
|
end
|
108
39
|
|
109
40
|
alias_method :stamp, :to_format
|
110
41
|
|
111
|
-
end
|
42
|
+
end
|
43
|
+
|
44
|
+
Date.send(:include, ActiveObject::Date) if ActiveObject.configuration.autoload_date
|